Skip to content
Newer
Older
100644 248 lines (187 sloc) 9.75 KB
2f1242f @naaman Add "Optionally Choose a JDK" section
naaman authored Sep 6, 2012
1 This quickstart will get you going with Java and the [Jetty](http://eclipse.org/jetty/) embedded web server, deployed to Heroku.
5f41d70 @jesperfj Added 'fork me' blurb and a link to maven
jesperfj authored Oct 6, 2011
2
dc0235a @jonmountjoy Consistency with Dev Center
jonmountjoy authored Mar 21, 2012
3 {.note}
4 Sample code for the [Java demo application](https://github.com/heroku/devcenter-java) is available on GitHub. Edits and enhancements are welcome.
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
5
6 ## Prerequisites
7
5f41d70 @jesperfj Added 'fork me' blurb and a link to maven
jesperfj authored Oct 7, 2011
8 * Basic Java knowledge, including an installed version of the JVM and [Maven 3](http://maven.apache.org/download.html).
2f1242f @naaman Add "Optionally Choose a JDK" section
naaman authored Sep 6, 2012
9 * Your application must run on the [OpenJDK](http://openjdk.java.net/) version 6, or 7 (8 is also available in beta).
10 * A Heroku user account. [Signup is free and instant.](https://api.heroku.com/signup/devcenter)
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
11
2f1242f @naaman Add "Optionally Choose a JDK" section
naaman authored Sep 6, 2012
12 ## Local workstation setup
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
13
dc0235a @jonmountjoy Consistency with Dev Center
jonmountjoy authored Mar 21, 2012
14 Install the [Heroku Toolbelt](https://toolbelt.herokuapp.com/) on your local workstation. This ensures that you have access to the [Heroku command-line client](http://devcenter.heroku.com/categories/command-line), Foreman, and the Git revision control system.
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
15
dc0235a @jonmountjoy Consistency with Dev Center
jonmountjoy authored Mar 21, 2012
16 Once installed, you can use the `heroku` command from your command shell. Log in using the email address and password you used when creating your Heroku account:
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
17
18 :::term
19 $ heroku login
20 Enter your Heroku credentials.
21 Email: adam@example.com
22 Password:
23 Could not find an existing public key.
24 Would you like to generate one? [Yn]
25 Generating new SSH public key.
26 Uploading ssh public key /Users/adam/.ssh/id_rsa.pub
27
28 Press enter at the prompt to upload your existing `ssh` key or create a new one, used for pushing code later on.
29
2f1242f @naaman Add "Optionally Choose a JDK" section
naaman authored Sep 6, 2012
30 ## Write your app
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
31
32 You can run any Java application on Heroku that uses Maven as build tool. As an example, we will write a web app using Jetty. Here is a basic servlet class that also contains a main method to start up the application:
33
34 ### src/main/java/HelloWorld.java
35
36 :::java
37 import java.io.IOException;
38 import javax.servlet.ServletException;
39 import javax.servlet.http.*;
40 import org.eclipse.jetty.server.Server;
41 import org.eclipse.jetty.servlet.*;
42
43 public class HelloWorld extends HttpServlet {
44
45 @Override
46 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
47 throws ServletException, IOException {
48 resp.getWriter().print("Hello from Java!\n");
49 }
50
51 public static void main(String[] args) throws Exception{
52 Server server = new Server(Integer.valueOf(System.getenv("PORT")));
53 ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
54 context.setContextPath("/");
55 server.setHandler(context);
56 context.addServlet(new ServletHolder(new HelloWorld()),"/*");
57 server.start();
58 server.join();
59 }
60 }
61
2f1242f @naaman Add "Optionally Choose a JDK" section
naaman authored Sep 6, 2012
62 ## Declare dependencies in `pom.xml`
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
63
c763041 @jesperfj Upgraded Jetty version and switched to using copy-dependencies instea…
jesperfj authored Jan 31, 2012
64 Cedar recognizes Java apps by the existence of a `pom.xml` file. Here's an example `pom.xml` for the Java/Jetty app we created above.
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
65
66 ### pom.xml
67
68 :::xml
69 <?xml version="1.0" encoding="UTF-8"?>
70 <project xmlns="http://maven.apache.org/POM/4.0.0"
71 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
72 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
73 <modelVersion>4.0.0</modelVersion>
74 <groupId>com.example</groupId>
75 <version>1.0-SNAPSHOT</version>
76 <artifactId>helloworld</artifactId>
77 <dependencies>
78 <dependency>
79 <groupId>org.eclipse.jetty</groupId>
80 <artifactId>jetty-servlet</artifactId>
c763041 @jesperfj Upgraded Jetty version and switched to using copy-dependencies instea…
jesperfj authored Jan 31, 2012
81 <version>7.6.0.v20120127</version>
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
82 </dependency>
83 <dependency>
84 <groupId>javax.servlet</groupId>
85 <artifactId>servlet-api</artifactId>
86 <version>2.5</version>
87 </dependency>
88 </dependencies>
89 <build>
90 <plugins>
91 <plugin>
c763041 @jesperfj Upgraded Jetty version and switched to using copy-dependencies instea…
jesperfj authored Jan 31, 2012
92 <groupId>org.apache.maven.plugins</groupId>
93 <artifactId>maven-dependency-plugin</artifactId>
94 <version>2.4</version>
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
95 <executions>
96 <execution>
c763041 @jesperfj Upgraded Jetty version and switched to using copy-dependencies instea…
jesperfj authored Jan 31, 2012
97 <id>copy-dependencies</id>
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
98 <phase>package</phase>
c763041 @jesperfj Upgraded Jetty version and switched to using copy-dependencies instea…
jesperfj authored Jan 31, 2012
99 <goals><goal>copy-dependencies</goal></goals>
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
100 </execution>
101 </executions>
102 </plugin>
103 </plugins>
104 </build>
105 </project>
106
107 Prevent build artifacts from going into revision control by creating this file:
108
109 ### .gitignore
110
111 :::term
112 target
113
2f1242f @naaman Add "Optionally Choose a JDK" section
naaman authored Sep 6, 2012
114 ## Build and run your app locally
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
115
116 Build your app locally:
117
118 :::term
ea77900 @jamesward change to mvn package
jamesward authored Oct 13, 2011
119 $ mvn package
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
120
7ffb67a @jesperfj README changes for last commit
jesperfj authored Jan 31, 2012
121 As part of the build, Maven gathers dependencies and copies them into the directory `target/dependency`. Start you app locally by setting the PORT environment variable and running Java with all dependencies on the classpath:
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
122
b1d7de6 @jamesward removed foreman
jamesward authored Oct 13, 2011
123 On Mac & Linux:
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
124
b1d7de6 @jamesward removed foreman
jamesward authored Oct 13, 2011
125 :::term
126 $ export PORT=5000
c763041 @jesperfj Upgraded Jetty version and switched to using copy-dependencies instea…
jesperfj authored Jan 31, 2012
127 $ java -cp target/classes:"target/dependency/*" HelloWorld
128
f44104c @jonmountjoy Article won't render without this fix.
jonmountjoy authored Feb 15, 2012
129 (double quotes needed to prevent expansion of `*`)
b1d7de6 @jamesward removed foreman
jamesward authored Oct 13, 2011
130
131 On Windows:
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
132
133 :::term
b1d7de6 @jamesward removed foreman
jamesward authored Oct 13, 2011
134 $ set PORT=5000
7ffb67a @jesperfj README changes for last commit
jesperfj authored Jan 31, 2012
135 $ java -cp target\classes;"target\dependency\*" HelloWorld
b1d7de6 @jamesward removed foreman
jamesward authored Oct 13, 2011
136
137 You should now see something similar to:
138
139 :::term
7ffb67a @jesperfj README changes for last commit
jesperfj authored Jan 31, 2012
140 2012-01-31 15:51:21.811:INFO:oejs.Server:jetty-7.6.0.v20120127
141 2012-01-31 15:51:21.931:INFO:oejsh.ContextHandler:started o.e.j.s.ServletContextHandler{/,null}
142 2012-01-31 15:51:21.971:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:5000
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
143
e9483fb @jamesward Make the localhost link an actual link
jamesward authored Oct 13, 2011
144 Open the app in your browser:
145 [http://localhost:5000](http://localhost:5000)
b1d7de6 @jamesward removed foreman
jamesward authored Oct 13, 2011
146
147
2f1242f @naaman Add "Optionally Choose a JDK" section
naaman authored Sep 6, 2012
148 ## Declare process types with a Procfile
b1d7de6 @jamesward removed foreman
jamesward authored Oct 13, 2011
149
7ffb67a @jesperfj README changes for last commit
jesperfj authored Jan 31, 2012
150 To run your web process on Heroku, you need to declare what command to use. We'll use `Procfile` to declare how our web process type is run.
b1d7de6 @jamesward removed foreman
jamesward authored Oct 13, 2011
151
152 Here's what the `Procfile` looks like:
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
153
154 :::term
c763041 @jesperfj Upgraded Jetty version and switched to using copy-dependencies instea…
jesperfj authored Jan 31, 2012
155 web: java -cp target/classes:target/dependency/* HelloWorld
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
156
c763041 @jesperfj Upgraded Jetty version and switched to using copy-dependencies instea…
jesperfj authored Jan 31, 2012
157 (note: no double quotes needed in Procfile)
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
158
2f1242f @naaman Add "Optionally Choose a JDK" section
naaman authored Sep 6, 2012
159 ## Optionally Choose a JDK
160 By default, OpenJDK 1.6 is installed with your app. However, you can choose to use a newer JDK by specifying `java.runtime.version=1.7` in the `system.properties` file.
161
162 Here's what a `system.properties` file looks like:
163
164 :::term
165 java.runtime.version=1.7
166
167 You can specify 1.6, 1.7, or 1.8 (1.8 is in beta) for Java 6, 7, or 8 (with lambdas), respectively.
168
169 ## Store your app in Git
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
170
171 We now have the three major components of our app: build configuration and dependencies in `pom.xml`, process types in `Procfile`, and our application source in `src/main/java/HelloWorld.java`. Let's put it into Git:
172
173 :::term
174 $ git init
175 $ git add .
176 $ git commit -m "init"
177
2f1242f @naaman Add "Optionally Choose a JDK" section
naaman authored Sep 6, 2012
178 ## Deploy to Heroku
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
179
2f1242f @naaman Add "Optionally Choose a JDK" section
naaman authored Sep 6, 2012
180 Create the app:
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
181
182 :::term
2f1242f @naaman Add "Optionally Choose a JDK" section
naaman authored Sep 6, 2012
183 $ heroku create
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
184 Creating stark-sword-398... done, stack is cedar
185 http://stark-sword-398.herokuapp.com/ | git@heroku.com:stark-sword-398.git
186 Git remote heroku added
187
188 Deploy your code:
189
190 :::term
191 $ git push heroku master
7ffb67a @jesperfj README changes for last commit
jesperfj authored Jan 31, 2012
192 Counting objects: 47, done.
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
193 Delta compression using up to 4 threads.
7ffb67a @jesperfj README changes for last commit
jesperfj authored Jan 31, 2012
194 Compressing objects: 100% (25/25), done.
195 Writing objects: 100% (47/47), 10.25 KiB, done.
196 Total 47 (delta 19), reused 42 (delta 17)
197
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
198 -----> Heroku receiving push
199 -----> Java app detected
2f1242f @naaman Add "Optionally Choose a JDK" section
naaman authored Sep 6, 2012
200 -----> Installing OpenJDK 1.6... done
201 -----> Installing Maven 3.0.3... done
202 -----> Installing settings.xml... done
7ffb67a @jesperfj README changes for last commit
jesperfj authored Jan 31, 2012
203 -----> executing /app/tmp/repo.git/.cache/.maven/bin/mvn -B -Duser.home=/tmp/build_3k0p14ghrmdzs -Dmaven.repo.local=/app/tmp/repo.git/.cache/.m2/repository -s /app/tmp/repo.git/.cache/.m2/settings.xml -DskipTests=true clean install
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
204 [INFO] Scanning for projects...
205 [INFO]
206 [INFO] ------------------------------------------------------------------------
207 [INFO] Building helloworld 1.0-SNAPSHOT
208 [INFO] ------------------------------------------------------------------------
209 ...
210 [INFO] ------------------------------------------------------------------------
211 [INFO] BUILD SUCCESS
212 [INFO] ------------------------------------------------------------------------
7ffb67a @jesperfj README changes for last commit
jesperfj authored Jan 31, 2012
213 [INFO] Total time: 10.062s
214 [INFO] Finished at: Tue Jan 31 23:27:20 UTC 2012
215 [INFO] Final Memory: 12M/490M
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
216 [INFO] ------------------------------------------------------------------------
217 -----> Discovering process types
218 Procfile declares types -> web
7ffb67a @jesperfj README changes for last commit
jesperfj authored Jan 31, 2012
219 -----> Compiled slug size is 948K
220 -----> Launching... done, v3
221 http://empty-fire-6534.herokuapp.com deployed to Heroku
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
222
223 Now, let's check the state of the app's processes:
224
225 :::term
226 $ heroku ps
7ffb67a @jesperfj README changes for last commit
jesperfj authored Jan 31, 2012
227 Process State Command
228 ------- ---------- ------------------------------------
229 web.1 up for 10s java -cp target/classes:target/dep..
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
230
231 The web process is up. Review the logs for more information:
232
233 :::term
234 $ heroku logs
235 ...
7ffb67a @jesperfj README changes for last commit
jesperfj authored Jan 31, 2012
236 2012-01-31T23:27:27+00:00 heroku[web.1]: Starting process with command `java -cp target/classes:target/dependency/* HelloWorld`
237 2012-01-31T23:27:28+00:00 app[web.1]: 2012-01-31 23:27:28.280:INFO:oejs.Server:jetty-7.6.0.v20120127
238 2012-01-31T23:27:28+00:00 app[web.1]: 2012-01-31 23:27:28.334:INFO:oejsh.ContextHandler:started o.e.j.s.ServletContextHandler{/,null}
239 2012-01-31T23:27:28+00:00 app[web.1]: 2012-01-31 23:27:28.373:INFO:oejs.AbstractConnector:Started SelectChannelConnector@0.0.0.0:8236
240 2012-01-31T23:27:29+00:00 heroku[web.1]: State changed from starting to up
241 2012-01-31T23:27:32+00:00 heroku[router]: GET empty-fire-6534.herokuapp.com/ dyno=web.1 queue=0 wait=0ms service=27ms status=200 bytes=17
242
243 Looks good. We can now visit the app with `heroku open`.
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
244
2f1242f @naaman Add "Optionally Choose a JDK" section
naaman authored Sep 6, 2012
245 ## Next steps: database-driven apps
35ba5d6 @jesperfj init
jesperfj authored Oct 6, 2011
246
29fb87f @jsimone Update README.md
jsimone authored May 2, 2013
247 The [Spring MVC Hibernate tutorial](http://devcenter.heroku.com/articles/spring-mvc-hibernate) will guide you through setting up a database-driven application on Heroku.
Something went wrong with that request. Please try again.