Jetty not looking in test-classes directory for resources - maven

I am using maven-jetty plugin and when I use jetty to run a webapp, the webapp does not look in the target/test-classes directory at all for a resource. However, it can find resources in the target/classes directory.
Here is the relevant part of my pom.xml
<configuration>
<webApp>target/webapp.war</webApp>
<testClassesDirectory>target/test-classes/</testClassesDirectory>
<useTestClasspath>true</useTestClasspath>
<stopPort>9966</stopPort>
<stopKey>stopKey</stopKey>
</configuration>
How can I make the maven-jetty plugin look in target/test-classes for resources

Because /src/test/java and /src/test/resources folders are only intended for unit testing. They are not added to maven-jetty-plugin CLASSPATH nor they are included in resulting WAR.

Related

Include and use native lib files (.so, .dylib) in "executable JAR"

I have a multimodule Spring Boot project with Maven. I am using spring-boot-maven-plugin to package this application into an executable JAR. This JAR is deployed to PCF (Pivotal Cloud Foundry).
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>my.AppMain</mainClass>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
Now I would like to use PDFTron library - they provided me with a JAR ,.so and .dylib files (.dll too but I dont need those). They said that the JAR has to be in the same directory as the so and dylib files in order to work properly.
I tried to use this library in the project but I cant make it work. I am running out of ideas, I believe I have read almost all possible posts to this topic.
I have tried:
load each of this files to maven repo, include each one as (dylib, so and pdfnet.jar), but it resulted in error message: Caused by: java.lang.UnsatisfiedLinkError: no PDFNetC in java.library.path:
put all the files (dylib, so and pdfnet.jar) into the src/main/resources, include just provided PDFNet.jar as but it resulted in error message: Caused by: java.lang.UnsatisfiedLinkError: no PDFNetC in java.library.path:
Only way that worked was when I used maven-dependency-plugin to unpack the PDFTron dependencies into the target directory and update the -Djava.library.path to point at this created directory - but this can be done only at my local machine, because PDFTron dependencies were unpacked at "package" phase. To the PCF we are depolying only the executable JAR, so there is no target directory at PCF, so this was not an "production ready" option.
My question is, how can I include these files into this "executable JAR" so it will work properly ? Is there a way to unpack them at runtime ? Or do I have to use other plugin than spring-boot-maven-plugin ?
I can modify the -Djava.library.path at PCF, but I would like to avoid deploying another zip/jar/folder along with this JAR (basically I want to avoid changing the CI/CD deploy script as it is not under my control - and right now we are deploying only the executable JAR)
I am using java version "11.0.8" and spring-boot version "2.2.8.RELEASE"
You only need two files, per-platform.
PDFNet.jar is for all platforms.
libPDFNetC.so for Linux
PDFNetC.dll for Windows
PDFNetC.dylib for macOS
You can see in the samples, there are RuntTest.[sh|exe] files that show the settings that you can use. For example
#!/bin/sh
TEST_NAME=AddImageTest
javac -cp ../../../Lib/PDFNet.jar *.java
java -Djava.library.path=../../../Lib -cp .:../../../Lib/PDFNet.jar $TEST_NAME
So -Djava.library.path= points to the folder containing libPDFNetC.so and/or PDFNetC.dll.
It sounds like you have deployment specific issue with your tech stack, but I assume there is a way, same as how you would deploy any images/fonts or other resources. Though maybe your tech stack puts some restrictions on where java.library.path can point to, but that should be in the documentation supplied by what you are using.

How to include external configuration resources to classpath in Spring (Spring Boot)?

I have 3rd party library that is configured by placing properties file on the root of the classpath. That library is using getClass().getResourceAsStream("/file.properties") to load that file. As it is 3rd party, it is unmodifiable. I have placed that configuration file into external resources directory (not to be mistaken with resources from eg. Maven's or Gradle's directory structure.
Directory structure is like this.
How to run/configure Spring boot to include content of resources directory to the classpath so getResourceAsStream wil work?
On SE application I would simply do java -jar myApp.jar with classpath in MANIFEST and that would work.
EDIT:
Just a word of clarification - putting configuration file inside project resources (along sources) is missing the whole point. I want to keep configuration externalized.
Here is how you can do it:
1.- Change your spring-boot-maven-plugin configuration to enable the Spring Boot PropertiesLauncher:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<layout>ZIP</layout>
</configuration>
</plugin>
</plugins>
</build>
2.- Launch your Spring Boot Application setting the location of the external properties file:
java -jar -Dloader.path=PATH_TO_PROPERTIES_FOLDER spring-ms-0.0.1-SNAPSHOT.jar
Assuming this folders:
/home/user/
|--- file.properties
|--- spring-mg-0.0.1-SNAPSHOT.jar
You should launch it like this: java -jar -Dloader.path=/home/user spring-ms-0.0.1-SNAPSHOT.jar

What is the best place for JavaDoc files in a Maven project using Tomcat?

I am regularly deploying a Maven project to a Tomcat server, using Travis CI. My project is a web app, so I have configured my pom.xml for building a WAR file, instead of a JAR:
...
<packaging>war</packaging>
...
With Maven, I can generate a directory containing all the JavaDoc files for my project; Maven puts them in the target/site/apidocs directory. But then, when I deploy my project, Travis doesn't perform any mvn site phase so I don't have my JavaDocs on the server.
Should I edit my pom.xml so that Maven puts the JavaDoc files somewhere in the src directory (instead of target) or is there a way to package the JavaDoc files together with the WAR file? I thought that I could create a docs/ directory inside src/main/webapp/. Specifically: is it "good practice" to generate my JavaDoc in src instead of target? if not, how can I have a WAR file containing my JavaDoc?
What would you suggest is the best thing to do?
I already know how to generate a standalone JAR containing my JavaDoc files (see here), but this is not what I'm looking for.
Use the site plugin https://maven.apache.org/plugins/maven-site-plugin/ and the javdoc plugin https://maven.apache.org/plugins/maven-javadoc-plugin/usage.html.
Add the following to your pom.xml
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<links>
<link>http://commons.apache.org/lang/api</link>
<link>http://java.sun.com/j2se/1.5.0/docs/api</link>
<link>http://this-one-will-not-work</link>
</links>
</configuration>
</plugin>
</plugins>
</reporting>
then mvn site:site your documentation will be in target/site you can also deploy it.

Maven: How to confine the application output to the target directory

I have a java application that uses maven for build management.
When I run the generated application jar with
java -jar myjar
the output files generated by the application end up in the projects root directory. So if I execute the jar in /my/project/dir and create a filewriter to write to logs/mylog
The resulting file ends up in
/my/project/dir/logs/mylog
Exactly as expected.
HOWEVER:
When maven surefire plugin executes the unit tests, the files end up in the module directory.
Say that i compile a maven project in /my/module.
The compiled files end up in /my/module/target/classes.
When maven executes these classes, through unit tests, the output of the same classes ends up in
/my/module/logs/mylog
I would like the files to end up in the target dir like
/my/module/target/logs/mylog
As this is where the class files reside.
So I am looking for a way to configure maven surefire to define the java classes' root directory to point to target instead of the module dir.
EDIT:
I have found this post:
Maven: change the directory in which tests are executed
That seems to attempt a fix to my problem. However, if i set the workingdirectory to my target dir, the tests can no longer find my resources, even if they are copied from the modules ${basedir} to ${basedir}/target
You should set your application working dir to ./target (or in a Maven property way: ${project.build.directory})
Solution:
By default, the maven surefire plugin executes its tests in the modules main directory.
In order to avoid this, set the workingdirectory of the plugin to the target directory.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>...</version>
<configuration>
<workingDirectory>${project.build.directory}</workingDirectory>
<basedir>${project.build.directory}</basedir>
</configuration>
</plugin>
Note that in case of tests that rely on some resources with root in the modules basedir, you need to copy these over. The easiest way i can find is with the resource plugin.
<build>
<resources>
<resource>
<directory>dependency</directory>
<targetPath>${project.build.directory}/dependency</targetPath>
</resource>
...
</build>
I can't tell you exactly how to do what you need to do because there is no real information
I can give you a hint about what to look at using.
Maven profiles can change the source, and behavior of Maven when they are selectively enabled.
Profiles are specifically designed to do just what you want to do.

Where should I put application configuration files for a Maven project?

I'm using the Maven Application Assembler plugin to generate stand-alone executables from my Java project. The application reads in configuration files, including Spring files. The Application Assembler plugin has an option (activated by default) to add a etc/ directory to the application's classpath, but what should I do to have the plugin copy my configuration files to this directory?
Or more generally, where is in Maven the kosher location for application configuration files that should NOT be packaged in the artifact?
You can also use resource filtering:
http://maven.apache.org/guides/getting-started/index.html#How_do_I_filter_resource_files
turn on filtering:
...
<build>
...
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
...
</build>
...
make a file under src/main/resources like: application.properties
application.properties
configprop.1=${param1}
configprop.2=${param2}
Then setup a profile and set some properties perhaps in a settings.xml
that sets different properties depending on if this is a dev or production build.
see: http://maven.apache.org/guides/introduction/introduction-to-profiles.html
I have different properties set depending on if this is the build server, dev or a production deployment
mvn -Denv=dev || mvn -Denv=dev-build || mvn -Denv=production
The maven link has a pretty good description.
For folks who have come to this more recently there is, since version 1.1 of the Application Assembler Plugin, the optional parameters configurationSourceDirectory and copyConfigurationDirectory. Please find them in an example POM.xml extract below:
<configuration>
<!-- Set the target configuration directory to be used in the bin scripts -->
<configurationDirectory>conf</configurationDirectory>
<!-- Copy the contents from "/src/main/config" to the target
configuration directory in the assembled application -->
<copyConfigurationDirectory>true</copyConfigurationDirectory>
<!-- Include the target configuration directory in the beginning of
the classpath declaration in the bin scripts -->
<includeConfigurationDirectoryInClasspath>
true
</includeConfigurationDirectoryInClasspath>
...
</configuration>
More information is here
You could try the maven assembly plugin. I used it in conjunction with the appassembler plugin.
Configure appassembler to point to whatever name you want for your configuration directory, if you don't want 'etc'. The assembly plugin assembles everything in its own output directory, so I configure the assembly plugin to copy the bin and repo dirs from the appassembler directory into its output dir, then I have it copy the config files (mine are in src/main/config) into the expected config dir. There is some duplication in this, because you are copying the appassembler outputs, but that didn't really bother me.
So what you have after executing the assembly plugin is your bin, repo, and config dir are all peer directories under the assembly output directory. You can configure it to have a different structure if you prefer, I just wanted mine to mirror the appassembler structure.
The nice thing is that you can also configure the assembly plugin to change your binaries to executables, which I could't see how to do with appassembler. And, if you then bind appassembler:assemble and assembly:single goals to the package phase, all you have to do is 'mvn package', and it assembles everything.
I don't know if I understand you correctly. But what I have done in the past for a project where I needed to copy configuration files, is use the Maven AntRun plugin. What I did is execute the plugin in the process-resources phase and copied my configuration files to the specified directory using the Ant copy task. The Assembler plugin executes in the package phase so it should pick up your configuration files if you put it in the right place. Hope this answers your question a little bit.
I had been looking for an answer to what I think is your question, or at least a very similar question. Maven allows you to specify directories for resources using the maven-resources-plugin. I have a few configuration files in one of my resource directories. I've noticed that by putting copies of those files in the etc/ directory that you mention (which is at the beginning of my CLASSPATH) I can change values in those files for use at run time. I then wanted to have that etc/ directory created with copies of everything from my resource directory by default. The copy-resources goal from the maven-resources-plugin allowed me to do that. This stanza from Examples > Copy Resources on the left sidebar (I'm limited to 2 links in this post) is what did it for me:
<project>
...
<build>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<id>copy-resources</id>
<!-- here the phase you need -->
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target/extra-resources</outputDirectory>
<resources>
<resource>
<directory>src/non-packaged-resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
...
</build>
...
</project>

Resources