This is a question about better separating the code for embedding jetty from the code for wiring up servlets.
I am trying to adapt this sample code such that I will be getting a runnable war, i.e. a war file that I can drop into an existing Jetty container, or run standalone using a command like java -jar webapp-runnable.war
.
The sample code belongs to these two blog posts: No.1, No.2.
I followed the GuiceServlet manual and created a web.xml
and GuiceServletContextListener
(see below), but they don't seem to get me very far with mvn jetty:run
; When I try to run mvn jetty:run
, I get the following error:
[main] DEBUG org.eclipse.jetty.util.log - Logging to Logger[org.eclipse.jetty.util.log] via org.eclipse.jetty.util.log.Slf4jLog
WARN:oejw.WebAppContext:main: Failed startup of context o.e.j.m.p.JettyWebAppContext@3cceafcb{/,file:/[...]/src/main/webapp/,STARTING}{file:/[...]/src/main/webapp/}
com.google.inject.ConfigurationException: Guice configuration errors:||1) Explicit bindings are required and com.google.inject.servlet.InternalServletModule$BackwardsCompatibleServletContextProvider is not explicitly bound.| while locating com.google.inject.servlet.InternalServletModule$BackwardsCompatibleServletContextProvider||1 error
at [stack strace clipped]
Here's my code. As mentioned before, I started with this repo on github.
1) I extracted the anonymous inner class of type AbstractModule from com.teamlazerbeez.http.HttpServerMain
and put it into a new class com.teamlazerbeez.http.HttpServerModule
. This class is now instantiated when creating the Guice Injector in HttpServerMain
(l36).
2) My web.xml
:
<?xml version="1.0" ?>
<web-app
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
metadata-complete="false"
version="3.0">
<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<listener>
<listener-class>com.teamlazerbeez.http.GuiceServletConfig</listener-class>
</listener>
</web-app>
3) My com.teamlazerbeez.http.GuiceServletConfig
:
public class GuiceServletConfig extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
//I know this code not come close to doing what I want, but I just don't know where to start
return Guice.createInjector(new HttpServerModule());
}
}
My question: How can I refactor the HttpServerMain
main
method and HttpServerModule
in such a way that the setup process described by them becomes usable to my GuiceServletConfig
? And what must GuiceServletConfig
look like for this to work?
I never got a war working as jar, so I always go for one of the two solutions. However, when using a war, its not hard to setup a embedded Jetty server that works in your IDE. To do that you can use a WebAppContext
to set it up using a web.xml
. See this documentation for an example. From there, everything should work as advocated on the Guice site.
However, this will not create a runnable war (like java -jar yourapp.war
) because jars have a different internal layout. However, if you want to you can use the jetty-runner to fix this using java -jar jetty-runner.jar yourapp.war
.