Fixed: Embedded Jetty Fails To Unpack With FileNotFoundException: Not a directory
I have built an executable .war with an embedded Jetty and all the dependencies packed in using the Maven Shade and War plugins. When I tried to run it (
The problem was that I use OS X which has a case-insensitive filesystem. A directory contained both the file LICENSE and the directory license/. When Jetty tried to unpack license/LICENSE.base64.txt, the check for the parent directory (license/) incorrectly succeeded (because it checked n
This was the original exception:
See JarResource.java:230 in jetty 9.0.5.x for the relevant code.
java -jar <my war>.war
) then I got a strange FileNotFoundException
during the unpack phase. It was strange because the unpack code actually checks whether a file's parent directory exists and creates it if it doesn't.The problem was that I use OS X which has a case-insensitive filesystem. A directory contained both the file LICENSE and the directory license/. When Jetty tried to unpack license/LICENSE.base64.txt, the check for the parent directory (license/) incorrectly succeeded (because it checked n
ew File("[..]/license/LICENSE.base64.txt").getParentFile().exists()
and that returned true because the file LICENSE already was there, and it wasn't distinguished from the actual directory license; .isDirectory()
would have at least failed.) The workaround was to exclude the offensive file from the archive:
<project ...>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
<finalName>fake-cc-proxy-with-dependencies</finalName>
<filters>
<filter>
<artifact>*</artifact>
<excludes>
<exclude>META-INF/LICENSE</exclude> <!-- conflicts on OS X with license/) -->
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
This was the original exception:
2013-10-02 13:44:16.557:WARN:oejw.WebAppContext:main: Failed startup of context o.e.j.w.WebAppContext@76959acc{/,null,null}{file:/Users/me/FakePM/target/fake-pm-with-dependencies.war}
java.io.FileNotFoundException: /private/var/folders/k0/2842tm752zv1dh4q77_gmgdr0000gn/T/jetty-0.0.0.0-8444-fake-pm-with-dependencies.war-_-any-/webapp/META-INF/license/LICENSE.base64.txt (Not a directory)
at java.io.FileOutputStream.open(Native Method)
at java.io.FileOutputStream.<init>(FileOutputStream.java:212)
at java.io.FileOutputStream.<init>(FileOutputStream.java:165)
at org.eclipse.jetty.util.resource.JarResource.copyTo(JarResource.java:237)
at org.eclipse.jetty.webapp.WebInfConfiguration.unpack(WebInfConfiguration.java:478)
at org.eclipse.jetty.webapp.WebInfConfiguration.preConfigure(WebInfConfiguration.java:72)
at org.eclipse.jetty.webapp.WebAppContext.preConfigure(WebAppContext.java:453)
at org.eclipse.jetty.webapp.WebAppContext.doStart(WebAppContext.java:489)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:69)
at org.eclipse.jetty.util.component.ContainerLifeCycle.start(ContainerLifeCycle.java:108)
at org.eclipse.jetty.server.Server.start(Server.java:342)
at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(ContainerLifeCycle.java:90)
at org.eclipse.jetty.server.handler.AbstractHandler.doStart(AbstractHandler.java:58)
at org.eclipse.jetty.server.Server.doStart(Server.java:290)
at org.eclipse.jetty.util.component.AbstractLifeCycle.start(AbstractLifeCycle.java:69)
at no.viatravel.poc.safecc.profilemaster.Main.startServerAndBlock(Main.java:123)
at no.viatravel.poc.safecc.profilemaster.Main.main(Main.java:38)
2013-10-02 13:44:16.575:INFO:oejs.ServerConnector:main: Started ServerConnector@478bc78e{HTTP/1.1}{0.0.0.0:8444}
See JarResource.java:230 in jetty 9.0.5.x for the relevant code.