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

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

Related

Spring Native custom name for generated executables

I want to change the name of the generated executables in Spring Native with Maven.
Default is the <artifactId> from the pom.xml.
If we want to specify the name of the resulting .jar file, we have an option to configure this with <finalName> inside the spring-boot-maven-plugin plugin configuration.
Is there a similar configuration property to allow the same behavior for the native-image-plugin?
I just found a solution using <imageName> inside the native-image-plugin configuration like:
pom.xml (only part of file shown)
...
<plugin>
<groupId>org.graalvm.buildtools</groupId>
<artifactId>native-maven-plugin</artifactId>
<configuration>
<imageName>app</imageName>
</configuration>
...

Externalize properties for command line tool using spring boot

I wanted to do a very simple thing which I had already done, which is using a spring boot packaged jar with some custom properties (private.properties containing a token) provided in a "config" directory. Currently I'm using a recent version of Spring Boot ("2.2.5.RELEASE").
My "config" directory was never taken into account and I had to do 2 very unintuitive things :
Complete spring boot maven plugin conf like this :
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<mainClass>${start-class}</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
and add these properties :
java -Dloader.home=. -Dloader.path=config -Dloader.config.name=private -jar my.jar
Could someone please tell me where is it officially documented (both actions) ? Is there a more simple way of doing this with less explicit parameters ?
Here is the answer :
"ZIP (alias to DIR): similar to the JAR layout using PropertiesLauncher."
source : https://docs.spring.io/spring-boot/docs/current/maven-plugin/reference/html/#repackage
and :
"PropertiesLauncher is a launcher for archives with user-configured classpath and main class via a properties file. This model is often more flexible and more amenable to creating well-behaved OS-level services than a model based on executable jars.
Looks in various places for a properties file to extract loader settings, defaulting to loader.properties either on the current classpath or in the current working directory. The name of the properties file can be changed by setting a System property loader.config.name (e.g. -Dloader.config.name=foo will look for foo.properties. If that file doesn't exist then tries loader.config.location (with allowed prefixes classpath: and file: or any valid URL). Once that file is located turns it into Properties and extracts optional values (which can also be provided overridden as System properties in case the file doesn't exist):
loader.path: a comma-separated list of directories (containing file resources and/or nested archives in *.jar or *.zip or archives) or archives to append to the classpath. BOOT-INF/classes,BOOT-INF/lib in the application archive are always used
loader.main: the main method to delegate execution to once the class loader is set up. No default, but will fall back to looking for a Start-Class in a MANIFEST.MF, if there is one in ${loader.home}/META-INF.
"
source : https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/loader/PropertiesLauncher.html

Spring boot application with apache axis

I am trying to run a spring boot jar which has axis2 dependencies in it. I am using spring boot maven plugin to build the jar (with dependencies). When I try to run my jar, I get the following exception in my console:
org.apache.axis2.AxisFault: The G:application\myapp\target\myapp.jar!\lib\axis2-1.6.1.jar file cannot be found.
at org.apache.axis2.deployment.repository.util.DeploymentFileData.setClassLoader(DeploymentFileData.java:111)
at org.apache.axis2.deployment.ModuleDeployer.deploy(ModuleDeployer.java:70)
at org.apache.axis2.deployment.repository.util.DeploymentFileData.deploy(DeploymentFileData.java:136)
at org.apache.axis2.deployment.DeploymentEngine.doDeploy(DeploymentEngine.java:813)
at org.apache.axis2.deployment.RepositoryListener.loadClassPathModules(RepositoryListener.java:222)
at org.apache.axis2.deployment.RepositoryListener.init2(RepositoryListener.java:71)
at org.apache.axis2.deployment.RepositoryListener.<init>(RepositoryListener.java:64)
at org.apache.axis2.deployment.DeploymentEngine.loadFromClassPath(DeploymentEngine.java:175)
at org.apache.axis2.deployment.FileSystemConfigurator.getAxisConfiguration(FileSystemConfigurator.java:135)
at ...
I then checked the structure of my jar. It has lib folder inside it, which contained all the jars (including the above mentioned axis jar). Attached is the screen shot of lib folder.
Following are the solutions which I have tried:
Placed axis jar in the same directory as application jar.
Created lib folder in the same directory as application jar and placed axis jar inside it.
Modified manifest file to include Class-Path: /lib/
None of the solutions has worked. However, when I run the application class in eclipse, the app starts and runs perfectly. But, once I create the jar, nothing seems to run.
Can anyone please help? Thanks in advance.
It looks like Axis can't cope with being run from a jar that's nested within another jar. It works fine in Eclipse as the Axis jar is available directly on the filesystem rather than being nested inside your Spring Boot application's jar file.
You can configure your application's fat jar file so that Spring Boot knows to unpack the Axis jar into a temporary location when it's run. If you're using Maven:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<requiresUnpack>
<dependency>
<groupId>org.apache.axis2</groupId>
<artifactId>axis2</artifactId>
</dependency>
</requiresUnpack>
</configuration>
</plugin>
</plugins>
</build>
And if you're using Gradle:
springBoot {
requiresUnpack = ['org.apache.axis2:axis2']
}
See the Spring Boot documentation for some further details.

Where should a custom Netbeans Platform conf. file be so that maven finds it?

Applications built on top of the NetBeans platform have a <myappdir>/etc/<myapp>.conf file determining, among other things, application JVM parameters. Historically, this file was a part of the NetBeans IDE installation (as far as I could tell), but starting with NB 6.9, custom files are now supported.
I am having trouble packaging a custom configuration file using Maven to build the application.
I imagine the app.conf property should have been set in the project's pom under project/build/pluginManagement/plugins like so:
<plugin>
...
<configuration>
<brandingToken>${brandingToken}</brandingToken>
<cluster>${brandingToken}</cluster>
<appConf>myapp.conf</appConf>
</configuration>
The maven module representing my application contained no prior source, so I created the src/main/nbm folder and placed myapp.conf in src/main/nbm. This isn't picked up by nbm-maven-plugin. and putting the conf file into src/main/resources doesn't make a difference.
So, can anyone explain how a NetBeans Platform application with a custom configuration file can be built using maven?
UPDATE:
With Tim's prod in the right direction, I found the answer documented on Geertjan's blog. The solution is to configure the nbm-maven-plugin like so in the application module pom:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>nbm-maven-plugin</artifactId>
<configuration>
<etcConfFile>src/main/resources/my.conf</etcConfFile>
</configuration>
</plugin>
</plugins>
</build>
BTW, if you need a second name with Geertjan, you're not really a NetBeans platform developer. ;)
Have a look at the documentation of the nbm:cluster-app plugin, specifically the part on the conf file.
As per my understanding that should allow you to replace the default one with a custom one that you create.

Jetty not looking in test-classes directory for resources

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.

Resources