Setting a Jetty resource for a static file embedded in the same jar file
I am trying to access a static resource (like first.html) packaged inside the same .jar file (testJetty.jar) which also has a class that runs the jetty server (v.8) (MainTest.java), I am not I can correctly install the resource base.
Structure of my jar file (testJetty.jar): testJetty.jar
-
first.html
-
MainTest.java
== Works fine on local machine, but when I wrap it in a jar file and then run it, it doesn't work, resulting in a "404: File not found" error.
I tried to set the resource base with the following values, all of which failed:
a) Tried installing it.
resource_handler.setResourceBase("."); // Results in directory containing the jar file, D:\Work\eclipseworkspace\testJettyResult
b) Tried getting it from getResource
ClassLoader loader = this.getClass().getClassLoader();
File indexLoc = new File(loader.getResource("first.html").getFile());
String htmlLoc = indexLoc.getAbsolutePath();
resource_handler.setResourceBase(htmloc); // Results in D:\Work\eclipseworkspace\testJettyResult\file:\D:\Work\eclipseworkspace\testJettyResult\testJetty1.jar!\first.html
c) Tried getting webdir
String webDir = this.getClass().getProtectionDomain()
.getCodeSource().getLocation().toExternalForm();
resource_handler.setResourceBase(webdir); // Results in D:/Work/eclipseworkspace/testJettyResult/testJetty1.jar
None of these three approaches worked.
Any help or alternative would be appreciated
Thank you abbas
source to share
Not unusual, I found a solution to my problem. 3rd approach mentioned by Stephen on Embedded Jetty: How to use the .war that is included in the .jar that Jetty starts from? works!
So I changed from Resource_handler to WebAppContext, where WebAppContext points to the same jar (testJetty.jar) and it works!
String webDir = MainTest.class.getProtectionDomain()
.getCodeSource().getLocation().toExternalForm(); ; // Results in D:/Work/eclipseworkspace/testJettyResult/testJetty.jar
WebAppContext webappContext = new WebAppContext(webDir, "/");
source to share
The solutions provided in this thread work, but I think some clarity on the solution might be helpful.
If you are building a fat jar and using the ProjectionDomain method, you might run into some problems because you are loading the whole jar!
class.getProtectionDomain()
.getCodeSource().getLocation().toExternalForm();
So the best solution is the other provided solution
contextHandler.setResourceBase(YourClass.class.getClassLoader().getResource("WEB-INF").toExternalForm());
The problem is that if you create a fat jar, you are not actually dumping your webapp resources to WEB-INF, but you are probably going into the root of the jar, so a simple workaround is to create a XXX folder and use the second approach:
contextHandler.setResourceBase(YourClass.class.getClassLoader().getResource("XXX").toExternalForm());
Or change the build tool to export the webapp files to the given directory. Maybe Maven does it on Jar for you, but gradle doesn't.
source to share
It looks like ClassLoader.getResource doesn't understand empty string or. or / as an argument. In my jar file, I had to move all stufs to WEB-INF (any other package that would run). So the code looks like
contextHandler.setResourceBase(EmbeddedJetty.class.getClassLoader().getResource("WEB-INF").toExternalForm());
so the context looks like this:
ContextHandler: 744 - started oejwWebAppContext @ 48b3806 {/, jar: file: /Users/xxx/projects/dropbox/ui/target/ui-1.0-SNAPSHOT.jar! / WEB-INF available}
source to share