4

I have a Spring MVC application where I use hibernate, freemarker. It is setup as a multi-maven project. I am using IntelliJ ultimate.

Jetty starts fine, but when I go to

http://localhost:8080/

It simply outputs the folders of my project, and I can view my source code in the browser!

Here is my setup currently:

    final Server server = new Server(8080);

    ProtectionDomain domain = HttpServer.class.getProtectionDomain();
    URL location = domain.getCodeSource().getLocation();

    WebAppContext webAppContext = new WebAppContext();
    webAppContext.setResourceBase(location.toExternalForm());
    webAppContext.setDescriptor(location.toExternalForm() + "/WEB-INF/web.xml");
    webAppContext.setContextPath("/");
    webAppContext.setParentLoaderPriority(true);

    server.setHandler(webAppContext);

    server.start();
    server.join();

My project layout is a multi-maven project (using intelli J), the layout is like:

/myapp/src/main/java/main.java (this contains the above code to start jetty)
/myapp/src/main/webapp
/myapp/src/main/webapp/assets
/myapp/src/main/webapp/WEB-INF
/myapp/src/main/webapp/WEB-INF/web-context.xml (spring config file)
/myapp/src/main/webapp/WEB-INF/web.xml
/myapp/src/main/webapp/WEB-INF/views/ (parent folder for my freemarker template files)
/myapp/src/main/webapp/WEB-INF/views/home/index.ftl 

My web.xml is:

<context-param>
    <param-name>log4jConfigLocation</param-name>
    <param-value>classpath*:log4j.properties</param-value>
</context-param>

 <servlet>
    <servlet-name>myapp</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>WEB-INF/web-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>myapp</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

When I run this in IntelliJ (11 ulimitate), I get the following output:

2012-08-15 19:17:11,611 [main] INFO  org.eclipse.jetty.server.Server - jetty-7.6.2.v20120308
2012-08-15 19:17:11,886 [main] INFO  org.eclipse.jetty.webapp.StandardDescriptorProcessor - NO JSP Support for /, did not find org.apache.jasper.servlet.JspServlet
2012-08-15 19:17:11,962 [main] INFO  org.eclipse.jetty.server.handler.ContextHandler - started o.e.j.w.WebAppContext{/,file:/Users/me/projects/myapp/myapp-web/target/classes/}
2012-08-15 19:17:12,021 [main] INFO  org.eclipse.jetty.server.AbstractConnector - Started SelectChannelConnector@0.0.0.0:8080

This obviously isn't working because when I run it using tomcat w/intelliJ I get a huge output for things like hibernate, spring, etc.

My pom.xml for the web module has:

..
 <packaging>war</packaging>
..
Blankman
  • 259,732
  • 324
  • 769
  • 1,199
  • see if this might help (it works) -> http://stackoverflow.com/a/10609507/169277 – ant Aug 15 '12 at 23:25
  • that is for production right? not for local development? I see scanInterval so that looks a development setup (in case it is different?) – Blankman Aug 15 '12 at 23:53
  • I'm not looking to run jetty in development mode, this is for production. – Blankman Aug 29 '12 at 04:04
  • Do you want to run an exploded WAR or the WAR itself? In either case, what is the absolute path to these resources, and have you confirmed that `URL location` points there? – jtoberon Aug 30 '12 at 10:23

4 Answers4

4

If you aim for running this in production, and you already use maven to build your application I'd suggest that you create the actual war package first:

mvn clean package

Then, once you have your webapp built create a new Jetty server that runs from a war archive (and not the source code).

As the Jetty manual states, it should be something like this:

    Server server = new Server(8080);

    WebAppContext webapp = new WebAppContext();
    webapp.setContextPath("/");
    webapp.setWar("path_to_the_war_file/your_app.war");
    server.setHandler(webapp);

    server.start();
    server.join();
Marek Dec
  • 954
  • 6
  • 8
  • Is there a difference between a war and jar package type? – Blankman Aug 30 '12 at 12:33
  • 2
    Technically war and jar are both .zip-like files (they use zip compression format). Jar is a collection of java classes (and some metadata) that usually forms a java library, war however is supposed to be a web application archive. Usually war archive contains web static resources, java class files, libraries (i.e. jars), container configuration files and metadata. – Marek Dec Aug 30 '12 at 13:07
  • @Blankman in any case your jetty is capable of running a war packaged app or an exploded version of it. The problem is that you set the resource base to your src directroywebAppContext.setResourceBase(location.toExternalForm()), which is wrong. The resource base is a directory tahat contains the static resources (with maven structure -> src/main/webapp). Also, if you want to run it in-place configure your IntelliJ to compile the classes to src/main/webapp/WEB-INF/classes. Hope this helps – Marek Dec Aug 30 '12 at 14:41
  • @MarekDec good point, he also seems to be referencing the web.xml wrong no? – loyalflow Aug 30 '12 at 20:14
  • @MarekDec so I ran mvn clean package, and my .war is located at target/myapp.war how can I reference that location in both testing locally and in production? – Blankman Aug 31 '12 at 02:48
  • @Blankman I'd try an absolute path first i.e. something like C:\dev\workspace\myapp\target\myapp.war on windows or /home/your_username/workspace/myapp/target/myapp.war on unix-like systems. – Marek Dec Aug 31 '12 at 07:02
  • Ok absolute path worked, but I can't keep it hard coded like that obviously. Thanks for your answer, it is def. starting up like it should, but now it fails saying it can't wire up some of my service classes, so it seems to be more of a spring issue, so i'm guessing it is a classpath or config file issue. – Blankman Aug 31 '12 at 16:07
  • @Blankman cool, put the war file in some location that is relative to the project, you'd be able to drop the absolute path and replace it witha relative one – Marek Dec Aug 31 '12 at 21:04
2

you're probably missing your context loader listener.

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
Matt
  • 11,523
  • 2
  • 23
  • 33
  • so this is needed when doing embedded jetty but not for using tomcat? (it works when I run it with tomcat via intellij) – Blankman Aug 16 '12 at 05:30
  • it should be needed no matter what. this is what starts up your spring config. – Matt Aug 16 '12 at 10:06
  • so it is works fine when I run the application using IntelliJ's tomcat setup, and I don't have the listner in my web.xml. – Blankman Aug 20 '12 at 23:12
0

Instead of invoking Jetty manually from main.java, refer to the Maven Jetty plugin in your pom.xml, and start your application by running mvn jetty:run

<build>
  <plugins>
    <plugin>
      <groupId>org.mortbay.jetty</groupId>
      <artifactId>jetty-maven-plugin</artifactId>
      <version>8.1.4.v20120524</version>
    </plugin>
  </plugin>
</build>

If instead your objective is to create an executable WAR file with an embedded copy of Jetty, you'd want to approach the task as so:

    final Connector connector = new SelectChannelConnector();
    connector.setPort(8080);

    final Server server = new Server();
    server.addConnector(connector);
    server.setStopAtShutdown(true);

    final WebAppContext context = new WebAppContext();
    context.setContextPath("/");
    context.setServer(server);

    final ProtectionDomain protectionDomain = Main.class.getProtectionDomain();
    final URL location = protectionDomain.getCodeSource().getLocation();
    context.setWar(location.toExternalForm());
    server.addHandler(context);

    server.start();
    server.join();
Mikael Gueck
  • 5,511
  • 1
  • 27
  • 25
0

Have you tried to set defaultsDescriptor parameter

webAppContext.setDefaultsDescriptor(JETTY_HOME+"/etc/webdefault.xml");

JETTY_HOME is where you installed jetty, you can find JETTY_HOME/etc/webdefault.xml contains essential settings.

Ted Shaw
  • 2,298
  • 14
  • 8