Hi,
Thanks for the tip. But I don't want the jar-with-dependencies, it doesn't play well with spring for instance. (It overwrites META-INF and such).
I think I solved the issue by implementing my own resource class that is returned from the DefaultServlet.getResource(). It works in my case, but I can't really see if there are any side-effects I don't know about (yet). So if any of the commiters can check that would be great.
The resource:
public class JarInJarResource extends URLResource {
private static final String JAR_FILE_PROTOCOL = "jar:file:/"; private ByteArrayOutputStream resourceOutput = new ByteArrayOutputStream(); private long lastModified;
public JarInJarResource(Resource resource) { super(resource.getURL(), null); }
@Override public boolean exists() { int firstIndexOfJarSeparator = this._urlString.indexOf("!/"); int lastIndexOfJarSeparator = this._urlString.lastIndexOf("!/"); try { JarFile mainJar = getMainJar(firstIndexOfJarSeparator); JarEntry jarInJar = getJarInJarAsJarEntry(firstIndexOfJarSeparator, lastIndexOfJarSeparator, mainJar); JarInputStream jarInJarStream = getJarInJarAsJarInputStream(mainJar, jarInJar); JarEntry jarEntry = null; while ((jarEntry = jarInJarStream.getNextJarEntry()) != null) { String fileNameRequested = this._urlString.substring(lastIndexOfJarSeparator + 2); if (jarEntry.getName().equals(fileNameRequested)) { IOUtils.copy(jarInJarStream, resourceOutput); lastModified = jarInJar.getTime(); return true; } } } catch (IOException e) { Log.debug(Log.EXCEPTION, e); } return false; }
private JarInputStream getJarInJarAsJarInputStream(JarFile jarFile, JarEntry entry) throws IOException { InputStream jarInJarInputStream = jarFile.getInputStream(entry); return new JarInputStream(jarInJarInputStream); }
private JarFile getMainJar(int firstIndexOfJarSeparator) throws IOException { String firstJar = this._urlString.substring(0, firstIndexOfJarSeparator).replaceAll(JAR_FILE_PROTOCOL, ""); return new JarFile(firstJar); }
private JarEntry getJarInJarAsJarEntry(int firstIndexOfJarSeparator, int lastIndexOfJarSeparator, JarFile jarFile) { String secondJar = this._urlString.substring(firstIndexOfJarSeparator + 2, lastIndexOfJarSeparator); return jarFile.getJarEntry(secondJar); }
@Override public synchronized InputStream getInputStream() throws IOException { return new ByteArrayInputStream(resourceOutput.toByteArray()); }
@Override public long lastModified() { return lastModified; } }
The Extension on DefaultServlet:
public class OneJarSupportingDefaultServlet extends DefaultServlet { private static final long serialVersionUID = 1L;
@Override public Resource getResource(String pathInContext) { Resource resource = super.getResource(pathInContext); if(resource instanceof JarResource) { return new JarInJarResource(resource); } return resource; } }
-- Lars On Apr 23, 2011, at 12:46 PM, Ondrej Zizka wrote:
Instead of one-jar, try the assembly plugin with it's `jar-with-dependencies` built-in descriptorRef:
http://ondra.zizka.cz/stranky/programovani/java/maven/maven-create-distribution-package.texy
Ondra
On Fri, 2011-04-22 at 09:29 +0200, Lars Vonk wrote:
Hi,
I am trying to create an application using embedded Jetty (version 7.4.0.v20110414) and want to package it using the onejar maven plugin (http://code.google.com/p/onejar-maven-plugin/).
Here is the code where I start jetty:
Server server = new Server(8180);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
context.setWelcomeFiles(new String[]{"index.html"});
ServletHolder servletHolder = new ServletHolder(new DefaultServlet());
URL resource = getClass().getResource("/web/");
String resourceBase = resource.toURI().toString();
servletHolder.setInitParameter("resourceBase", resourceBase);
context.addServlet(servletHolder, "/");
server.setHandler(context);
server.start();
When I do java -jar onejar.jar and go to http://localhost:8180/index.html I get a 404.
My onejar.jar looks like this:
onejar.jar
main/myapp.jar
main/myapp.jar/web/index.html
(Rest omitted for readability).
I debugged through the application and noticed it throws (and ignores) an exception in the org.eclipse.jetty.util.resource.JarFileResource class in the method exists() in this piece of code:
try
{
JarURLConnection c=(JarURLConnection)((new URL(_jarUrl)).openConnection());
c.setUseCaches(getUseCaches());
jarFile=c.getJarFile();
}
catch(Exception e)
{
Log.ignore(e);
}
The _jarUrl contains: jar:file:/target/onejar.jar!/main/myapp.jar!/web/index.html and throws a ZipException when doing c.getJarFile(): java.util.zip.ZipException: error in opening zip file.
Does anyone has experience in using embedded jetty with the mentioned onejar plugin? What I'd like to do is do java -jar myjar.jar where myjar contains everything that is needed, no additional files and such.
Extra information:
I also created a unit test for this asfollows:
@Test
public void defaultServlet() throws Exception {
final Server server = new Server(8181);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
context.setWelcomeFiles(new String[]{"index.html"});
DefaultServlet defaultServlet = new DefaultServlet();
ServletHolder servlet = new ServletHolder(defaultServlet);
servlet.setInitParameter("resourceBase", "jar:file:/target/onejar.jar!/main/myapp.jar!/web/");
context.addServlet(servlet, "/");
server.setHandler(context);
server.start();
Resource resource = defaultServlet.getResource("/index.html");
assertNotNull(resource);
server.stop();
}
This tests succeeds, meaning resource is not null. Does a real request use something else to find the resources that the getResource method on the servlet?
Thanks in advance,
Lars
_______________________________________________
jetty-users mailing list
jetty-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/jetty-users
_______________________________________________ jetty-users mailing list jetty-users@xxxxxxxxxxx https://dev.eclipse.org/mailman/listinfo/jetty-users
|