The Holy Java

Building the right thing, building it right, fast

Fixed: Embedded Jetty Fails To Unpack With FileNotFoundException: Not a directory

Posted by Jakub Holý on October 4, 2013

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 (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 new 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 ...>
                                <transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
                                        <exclude>META-INF/LICENSE</exclude> <!-- conflicts on OS X with license/) -->

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} /private/var/folders/k0/2842tm752zv1dh4q77_gmgdr0000gn/T/jetty- (Not a directory)
    at Method)
    at org.eclipse.jetty.util.resource.JarResource.copyTo(
    at org.eclipse.jetty.webapp.WebInfConfiguration.unpack(
    at org.eclipse.jetty.webapp.WebInfConfiguration.preConfigure(
    at org.eclipse.jetty.webapp.WebAppContext.preConfigure(
    at org.eclipse.jetty.webapp.WebAppContext.doStart(
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(
    at org.eclipse.jetty.util.component.ContainerLifeCycle.start(
    at org.eclipse.jetty.server.Server.start(
    at org.eclipse.jetty.util.component.ContainerLifeCycle.doStart(
    at org.eclipse.jetty.server.handler.AbstractHandler.doStart(
    at org.eclipse.jetty.server.Server.doStart(
    at org.eclipse.jetty.util.component.AbstractLifeCycle.start(
    at no.viatravel.poc.safecc.profilemaster.Main.startServerAndBlock(
    at no.viatravel.poc.safecc.profilemaster.Main.main(
2013-10-02 13:44:16.575:INFO:oejs.ServerConnector:main: Started ServerConnector@478bc78e{HTTP/1.1}{}

See in jetty 9.0.5.x for the relevant code.

Sorry, the comment form is closed at this time.

%d bloggers like this: