Serving static files from a jar file - java

I'm using grizzly StaticHttpHandler to serve the static files from an absolute path:
httpServer.getServerConfiguration().addHttpHandler(new StaticHttpHandler("/home/user/.../project/src/main/resources/static));
How can I package and serve the static files from the final fat jar generated by mvn assembly:single?
my part of my pom.xml file looks like
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>*</include>
</includes>
</resource>
</resources>
</build>

The given configuration
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>*</include>
</includes>
</resource>
</resources>
</build>
is not neccessary cause it's default.
Furthermore to get resources which are located there it's good to know that they will be packaged into the corresponding jar which can be accessed via
this.getClass().getResourceAsStream("/TheThingYoulikeToAccess.jpg"));
This defines a resource which is within the given jar file.

You can serve static files from a jar file using CLStaticHttpHandler like:
server.getServerConfiguration().addHttpHandler(
new CLStaticHttpHandler(new URLClassLoader(new URL[] {
new File("/home/myname/myjarfile.jar").toURI().toURL()}), // Path to the jar file
"my/jar/staticfiles-insider-jar/"), // the static files path inside the jar file
"/jarstatic"); // context-path

Related

source [Beans.xml] cannot be opened because it does not exist

I'm trying to package a Spring Project with Maven, but the Beans.xml file is missing.
A lot of people suggest to put the Bean.xml file in the main/resources, but it does not work for me. I think that only works for Eclipse user and I'm just compiling in the terminal using 'mvn clean install'.
Stupid mistake, inside my pom file the directory was like the following:
<build>
<resources>
<resource>
<directory>src/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<excludes>
<exclude>**/*.jpeg</exclude>
<exclude>**/*.gif</exclude>
</excludes>
</resource>
My resources folder was not inside src/main/resources, but src/resources.
And when I open my jar file the Beans.xml file this there and the code runs without error.

Replace test property values at the time of maven build

I have a test.properties file located in: $PROJECT_HOME/src/test/resources with the following content:
hostname=${host}
I also have a main.properties file located in: $PROJECT_HOME/src/main/resources with the same content.
Then I specified the followinging lines in the pom-file of my project.
<properties>
<host>localhost</host>
</properties>
<build>
<resources>
<!-- Filter resource files -->
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
....
</build>
After executing a mvn clean install I see that the main.properties in my target folder is replaced with the localhost value. However the property in my test.properties is not...
My first idea was to adapt the resources as this:
<properties>
<host>localhost</host>
</properties>
<build>
<resources>
<!-- Filter resource files -->
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
....
</build>
When building now, the test.properties file is replaced with the localhost value, but is placed into the classes folder in the target. In test-classes, there is still the test.properties file without the replaced value...
Is there a way to also replace the value in the test-classes folder?
My idea is to work on my local server with the localhost value without specifying it as a parameter and to overwrite this value with an alternate host when performing integration tests against a test server. In this case I specify the value -Dhost=<> on our continuous integration system.
This should work (although test.properties will not end up in your classes folder and test-classes would have both test.properties and main.properties with the replaced value which I think was what you wanted but wasn't sure).
<resources>
<!-- Filter resource files -->
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<testResources>
<!-- Filter test resource files -->
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</testResource>
</testResources>
Also, you may want to have two properties, ${host} (referenced in host.properties) and ${test.host} (referenced in test.properties), otherwise if you specify -Dhost during an integration build it will replace the value in both the host.properties and the test.properties. This way you can specify -Dtest.host to change which host you are using for integration tests but not the host that is set when you deploy.

Configuring PropertySourcesPlaceholderConfigurer for WAR

I am trying to create a WAR that can use a spring properties file, but I seem to be having some issues with it.
I can see that my properties file in the base directory structure in target, and in a WAR when I make an exploded war. When I try to make a normal WAR, though, and deploy it, I a resource not found exception, specifically:
org.springframework.beans.factory.BeanInitializationException: Could not load properties; nested exception is java.io.FileNotFoundException: class path resource [service.properties] cannot be opened because it does not exist
From Jetty I have no such issue.
Here's my spring java configuration of the resource:
#Bean
public static PropertySourcesPlaceholderConfigurer propertyPlaceHolderConfigurer() {
PropertySourcesPlaceholderConfigurer props = new PropertySourcesPlaceholderConfigurer();
props.setLocations(new Resource[] { new ClassPathResource("service.properties") });
return props;
}
And here's the relevant part of my POM. I added in the WAR configuration because that's what maven seemed to say to do here, but it didn't seem to help.
<build>
<resources>
<resource>
<directory>src/main/config/local</directory>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<goals>
<goal>war</goal>
</goals>
<configuration>
<webResources>
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>src/main/config/local</directory>
<includes>
<include>**/*.properties</include>
</includes>
</resource>
</webResources>
</configuration>
</plugin>
Anyone know what I'm doing wrong? Thanks!
Are you sure that your properties file is inside WEB-INF folder? If it outside and is just included in the root of the war file then it won't be found in the classpath. See maven-war-plugin documentation - to override default location (root of the war file) you need to add
<targetPath>WEB-INF</targetPath>

jar file gets corrupted while building with maven

while building a war file i am copying a set of jars from a location to a folder inside the war. While the files do get copied , however i think they get corrupted because the same class files of the jar when taken outside the war opens with a debugger while it does not open after taking from war file .
This is a part of my war pom.xml where i copy the jars
<execution>
<id>copy-jars</id>
<phase>process-resources</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/${project.artifactId}-${buildNumber}/somefolder</outputDirectory>
<resources>
<resource>
<directory>SomeSourceDirectory</directory>
<filtering>true</filtering>
<includes>
<include>**/**</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
SomeSourceDirectory has some jars and some other files
The result is:
myWar/somefolder/a.jar but when i open the classes inside this jar in a debugger..i get error in WinZip that
Invalid compressed data to extract.
Severe Error: Compressed data is invalid
However the same class file can be viewed when i view it in original folder i.e outside the war.
So is there a mistake while copying the jars?
Thanks.
Remove <filtering>true</filtering>, it corrupts the jar files.
Also, you can continue benefit to use maven filtering without corrupting jars inside.
We choose to exclude jar from filtered extensions.
In th pluginManagement section of the parent pom we put this configuration
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.5</version>
<configuration>
<encoding>${project.build.sourceEncoding}</encoding>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>jar</nonFilteredFileExtension>
<nonFilteredFileExtension>pdf</nonFilteredFileExtension>
<nonFilteredFileExtension>swf</nonFilteredFileExtension>
<nonFilteredFileExtension>zip</nonFilteredFileExtension>
<nonFilteredFileExtension>bz2</nonFilteredFileExtension>
<nonFilteredFileExtension>gz</nonFilteredFileExtension>
<nonFilteredFileExtension>acp</nonFilteredFileExtension>
<nonFilteredFileExtension>bin</nonFilteredFileExtension>
<nonFilteredFileExtension>odt</nonFilteredFileExtension>
<nonFilteredFileExtension>doc</nonFilteredFileExtension>
<nonFilteredFileExtension>xls</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
Note we added jar extensions as well as default maven excluded filetypes (its a zip after all).
Besides avoiding corruption of the archive it also speeds up the process as it does not have to filter large files.
Try Maven Assembly Plugin. It's my favourite plugin to add custom resources to a *.war file. See also Pre-defined Descriptor Files.
I had a similar error when I've added
<copy ...>
<fileset ... />
<filterchain>
<tokenfilter>
<replacestring from="..." to="..." />
</tokenfilter>
</filterchain>
</copy>
to my copy task in ANT. It corrupted the jar files when copying them.
I've solved this by applying the filter ONLY on the targeted text files and not on jar files.
Just as addition to the other answers, the other option is to enable the filtering only for the resources that require filtering:
<build>
...
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources</directory>
<includes>
<include>core.properties</include>
</includes>
</resource>
<resource>
<filtering>false</filtering>
<directory>src/main/resources</directory>
<includes>
<include>pdf/color_profile/sRGB.icc</include>
</includes>
</resource>
</resources>
</build>

With Maven, how do you filter a file that is not a resource but you want it to use the same filters as resources?

With Maven, how do you filter a file that is not a resource but you want it to use the same filters as resources?
Here is my resources tag in my pom.xml. The first two are working fine, because I ultimately want these files to go into the classpath. However, with the 3rd and final resource tag, I want to make sure it goes into the WEB-INF directory rather than the classes directory. My code, which I thought ought to work, actually doesn't work. How can I make this happen?
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/dict</directory>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/webapp/WEB-INF</directory>
<targetPath>WEB-INF</targetPath>
<includes>
<include>myapplication-servlet.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
That's a webapp resource and should be dealt with as such by configuring the maven war plugin appropriately. Define the resource there and turn on filtering, and you'll get the results you expect.

Categories