How to externalise .properties files when deploying a Spring Boot WAR in Wildfly Server? - spring

I am developing a web application using Spring Boot, and want to generate war instead of jar.
It works fine using the conversion from jar to war described here : http://spring.io/guides/gs/convert-jar-to-war/
But I want to externalize the application.properties from the war, because I want to be able to modify it without opening the war archive.
I already defined the spring-boot-maven plugin.
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<classifier>spring-boot</classifier>
<mainClass>
com.application.Application
</mainClass>
</configuration>
</execution>
</executions>
</plugin>
I think I need to add Dependency: config to my manifest file.
So, I've done it like that :
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Dependencies>config</Dependencies>
</manifestEntries>
</archive>
</configuration>
</plugin>
But when I launch the Application.war on Wildfly 8.4, I've got this
{"JBAS014671: Failed services" => {"jboss.module.service.\"deployment.Application.war\".main" => "org.jboss.msc.service.StartException in service jboss.module.service.\"deployment.screening.war\".main: JBAS018759: Failed to load module: deployment.Application.war:main
Caused by: org.jboss.modules.ModuleNotFoundException: config:main"}}
I would like that my application start with my custom MANIFEST.MF (with Dependency: config) so that I can externalize my application.properties file.
Thank you.

The problem was on the server side !
When you specify a package, you need to add a module.xml file with a Wildfly server.
So in modules/config/main/, I've added my application.properties and a module.xml file that contains :
<?xml version="1.0" encoding="UTF-8"?>
<module xmlns="urn:jboss:module:1.1" name="config">
<resources>
<resource-root path="."/>
</resources>
</module>
Thank you for your response #NielsNet.

Related

Error running JavaFX Jar file built from NetBeans using Maven

I'm using the current NetBeans, and have just created a simple JavaFX project with the Maven compiler.
It runs, cleans, builds etc. perfectly fine, no errors, when in NetBeans.
However, when I navigate to the folder "...Documents\NetBeansProjects\Simple Banking Application\target" and run the executable Jar file, nothing happens. So I tried to run it manually via command line (Java -jar file.jar) it shows me the reason is because of an error:
No main manifest attribute
After searching, I found a supposed solution, involving adding these few lines to the POM.xml:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.mycompany.mavenproject2.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
Unfortunately, that just causes a new error:
Error: Could not find or load main class com.mycompany.mavenproject2.App
Caused by: java.lang.NoClassDefFoundError: javafx/application/Application
I'm at a loss, and I'm wondering if I'm just missing something obvious. A couple of preliminary notes:
-I made sure to set this as my main project in NB
-I'm using default configuration
-I've tried cleaning and building, and just building as well, everything runs without any errors in NB
-I've not modified anything settings-wises
-I did refactor the project from mavenproject2 to Simple Banking Application, but I did so using NB's renaming options so that it does so 'safely'. (For the artifactID I had to remove the whitespaces)
-I've made sure all the .class files and .java files are in the project folder (.java are found in src, .class are found in target>classes)
Just in case, here is my entire POM.xml document:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany</groupId>
<artifactId>SimpleBankingApplication</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>13</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>11</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.mycompany.mavenproject2.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.4</version>
<configuration>
<mainClass>com.mycompany.mavenproject2.App</mainClass>
</configuration>
<executions>
<execution>
<!-- Default configuration for running -->
<!-- Usage: mvn clean javafx:run -->
<id>default-cli</id>
</execution>
<execution>
<!-- Configuration for manual attach debugging -->
<!-- Usage: mvn clean javafx:run#debug -->
<id>debug</id>
<configuration>
<options>
<option>-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=localhost:8000</option>
</options>
</configuration>
</execution>
<execution>
<!-- Configuration for automatic IDE debugging -->
<id>ide-debug</id>
<configuration>
<options>
<option>-agentlib:jdwp=transport=dt_socket,server=n,address=${jpda.address}</option>
</options>
</configuration>
</execution>
<execution>
<!-- Configuration for automatic IDE profiling -->
<id>ide-profile</id>
<configuration>
<options>
<option>${profiler.jvmargs.arg1}</option>
<option>${profiler.jvmargs.arg2}</option>
<option>${profiler.jvmargs.arg3}</option>
<option>${profiler.jvmargs.arg4}</option>
<option>${profiler.jvmargs.arg5}</option>
</options>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<name>Simple Banking Application</name>
</project>
You don't have the JavaFX components on your module path.
You can use a JDK which includes JavaFX (e.g. Azul JDK FX or Liberica Full JDK).
OR, you can follow the instructions below.
See the section on setting the VM arguments for running a JavaFX application as a jar file.
java --module-path /path/to/javafx-sdk-14/lib --add-modules javafx.controls,javafx.fxml -jar myJar.jar
You are using netbeans + maven, so refer to the official documentation openjfx.io JavaFX and NetBeans: modular with maven for more information. It discusses VM arguments for the Java module system to support JavaFX as well as creating runtime images using jlink.
If you don't know or understand the basics of the Java module system, then you should take some time to study and learn it from an appropriate tutorial. That will help you better understand the command line arguments required for the module system as well as the module-info.java alternative.
See the packaging instructions in the JavaFX tag which provide information on packaging alternatives (e.g. jlink and jpackage).
Use up-to-date software (e.g. JDK/JavaFX 18 and the maven-jar-plugin 0.0.8).
Don't use the maven-jar-plugin addClasspath option to build your jar when you have JavaFX component dependencies. The JavaFX components are not designed to be run from the classpath.

Executable JAR - JVM Arguments - Externalized Config Properties - Spring Boot Maven Plugin

We have a spring boot app with externalized configuration in a properties file. Executing the jar file like so works:
java -jar -Dspring.config.location="application.properties" app.jar
Executing the jar directly like below works, but without the properties file. Right now, none of these options below take the properties file.
./app.jar
./app.jar -Dspring.config.location="file:./application.properties"
I was hoping we could do something in the pom.xml or in the command that executes to achieve this.
FYI, we have this plugin in the pom.xml to build us the jar file:
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<executable>true</executable>
<includeSystemScope>true</includeSystemScope>
<!-- This below does not work -->
<!-- <jvmArguments> -->
<!-- -Dspring.config.location=application.properties -->
<!-- </jvmArguments> -->
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
Create file: app.conf (filename is the same as your jar) with content:
JAVA_OPTS="-Dspring.config.location=application.properties"
Similar question was answered here. Documentation for customizing start script can be found here.

Which dependencies do I have to include in a Maven Apache Storm Project?

I am pretty new to Apache Storm and Maven projects, so I tried to follow this "tutorial" (which from my point of view is not a tutorial at all):
http://storm.apache.org/releases/current/Creating-a-new-Storm-project.html
There is a huge pom.xml referenced (https://github.com/apache/storm/blob/v1.1.1/examples/storm-starter/pom.xml) which shall be used as basis for a new project. I tried to figure out what to copy into my project pom.xml. So I decided to start with the apache core dependency first. My pom.xml looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>groupId</groupId>
<artifactId>StormTest</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.storm</groupId>
<artifactId>storm-core</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.5.0</version>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>java</executable>
<includeProjectDependencies>true</includeProjectDependencies>
<includePluginDependencies>false</includePluginDependencies>
<classpathScope>compile</classpathScope>
<mainClass>${storm.topology}</mainClass>
<cleanupDaemonThreads>false</cleanupDaemonThreads>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.3</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
<appendAssemblyId>false</appendAssemblyId>
<finalName>StormTest-1.0-SNAPSHOT_dep</finalName>
<archive>
<manifest>
<mainClass>de.arphi.bi.WordCountTopology</mainClass>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>${basedir}/resources</directory>
<filtering>false</filtering>
<includes>
<include>log4j2.xml</include>
</includes>
</resource>
</resources>
</build>
</project>
This even works when it is about runing maven and building / packaging a jar. The outcome are two jar files (a small one without dependencies and a bigger one with dependencies). I cannot run the smaller one because it says "main manifest not found". But I can run the bigger one by executing the following command:
storm -jar StormTest-1.0-SNAPSHOT_dep.jar
Actually the runs on my locally installed apache storm 1.1.1 (I have some System.out.printlns ...) but I get an exception:
2018-01-02 21:38:31,864 main ERROR Unable to create file C:\Users\Artur\Desktop\Bi\apache-storm-1.1.1\logs/access-web-${sys:daemon.name}.log java.io.IOException: Die Syntax für den Dateinamen, Verzeichnisnamen oder die Datenträgerbezeichnung ist falsch
at java.io.WinNTFileSystem.canonicalizeWithPrefix0(Native Method)
at java.io.WinNTFileSystem.canonicalizeWithPrefix(WinNTFileSystem.java:451)
at java.io.WinNTFileSystem.canonicalize(WinNTFileSystem.java:422)
at java.io.File.getCanonicalPath(File.java:618)
at java.io.File.getCanonicalFile(File.java:643)
at org.apache.logging.log4j.core.util.FileUtils.makeParentDirs(FileUtils.java:134)
at org.apache.logging.log4j.core.appender.rolling.RollingFileManager$RollingFileManagerFactory.createManager(RollingFileManager.java:573)
at org.apache.logging.log4j.core.appender.rolling.RollingFileManager$RollingFileManagerFactory.createManager(RollingFileManager.java:554)
at org.apache.logging.log4j.core.appender.AbstractManager.getManager(AbstractManager.java:112)
at org.apache.logging.log4j.core.appender.OutputStreamManager.getManager(OutputStreamManager.java:114)
at org.apache.logging.log4j.core.appender.rolling.RollingFileManager.getFileManager(RollingFileManager.java:155)
at org.apache.logging.log4j.core.appender.RollingFileAppender$Builder.build(RollingFileAppender.java:131) at org.apache.logging.log4j.core.appender.RollingFileAppender$Builder.build(RollingFileAppender.java:60)
at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:122)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:952)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:892)
at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:884)
at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:508) at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:232)
at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:244)
at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:545)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:617)
at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:634)
at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:229)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:152)
at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:45)
at org.apache.logging.log4j.LogManager.getContext(LogManager.java:194)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getContext(AbstractLoggerAdapter.java:122)
at org.apache.logging.slf4j.Log4jLoggerFactory.getContext(Log4jLoggerFactory.java:43)
at org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(AbstractLoggerAdapter.java:46)
at org.apache.logging.slf4j.Log4jLoggerFactory.getLogger(Log4jLoggerFactory.java:29)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:358)
at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:383)
at org.apache.storm.topology.BasicBoltExecutor.<clinit>(BasicBoltExecutor.java:28)
at org.apache.storm.topology.TopologyBuilder.setBolt(TopologyBuilder.java:215)
at de.arphi.bi.WordCountTopology.main(WordCountTopology.java:22)
It says something about the syntax for creating a directory is wrong. And I know that it is about logging. I played arroung with different other dependencies (log4j, slf4j) and tried ecen to exclude dependecies without any success. I cannot get rid of this error.
Any ideas? I think that I am missing a dependency or that I have to exclude some parts of my pom.xml. But since I am not an Maven expert it is really hard for me to figure out what I have to adapt here.
I agree that storm-starter has gotten pretty big, and we should maybe have more of a minimal example.
First you should set the storm-core dependency to "provided" scope. When you deploy the topology to Storm, your jar will use the storm-core jar present in the Storm installation, so you shouldn't also put it in your fat jar.
<dependency>
<groupId>org.apache.storm</groupId>
<artifactId>storm-core</artifactId>
<version>1.1.1</version>
<scope>provided</scope>
</dependency>
When your topology runs on Storm, it will use the Log4j2 configuration in the log4j2/worker.xml file in your Storm installation. You shouldn't include your own log4j2.xml. If you need to set specific log levels, you can either modify worker.xml or use the CLI as described at http://storm.apache.org/releases/1.1.1/dynamic-log-level-settings.html.
Other than that your pom looks fine. I don't know why you have exec-maven-plugin in there (Edit: I see it's also in storm-starter, I think it's a leftover from when it was possible to run storm-starter in local mode. You shouldn't need it), and I might replace maven-assembly-plugin with the shade plugin, but I'd expect your topology to work regardless.
Thank Stig Rohde Døssing. Finally I found the origin for my exception base on your hint regarding the log4j2/worker.xml. The issue was not in the worker.xml, but in the cluster.xml which is located in the same directory.
When reading my Exception shown here, you can see that Java complains about creating a system path ("access-web-${sys:daemon.name}.log"). I found the placeholder sys:daemon.name in the cluster.xml and replaced it with something static like "access-web-mysysdaemonname.log". That fixed the issue. I have no idea why this placeholder could not be resolved by the system while there was no trouble with other placeholders.
Thanks for the hints. Topic can be closed.

Create the configuration file at maven install and without or before feature install for Karaf

In my project, in the bundle module, at resource directory, I have my sample startup.cfg file. This file contains properties I want to use at the startup. In the bundle pom.xml I have the following.
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/classes/startup.cfg</file>
<type>cfg</type>
<classifier>config</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
And in my feature xml, I have,
<feature name="my-sample-feature" description="Sample service" version='${project.version}'>
<bundle>mvn:org.sample.app/service.implementation/{{VERSION}}</bundle>
<configfile finalname="/etc/org.sample.app.startup.cfg">mvn:mvn:org.sample.app/service.implementation/{{VERSION}}/cfg/config</configfile>
</feature>
In feature xml, I have added,
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>service.implementation</artifactId>
<version>${project.version}</version>
<classifier>config</classifier>
<type>cfg</type>
</dependency>
This feature is a startup feature too. Now, when I install the feature in a karaf container or in this case when I spin up the karaf, only then the etc/org.sample.app.startup.cfg is created. My target is simple, to have this conf file always at etc/ independent of the feature is installed or not.
The cfg file are deployed into etc folder when installing the feature . If you want it to be present independent of the feature is installed or not, this means that you have to deploy it manually to etc and this is more simple after attaching the cfg to your artifact as you did in your pom.
Remember that if you want to follow best pratices (especially in a production environnement), don't separate cfg deployment from it's origin feature.

Deploy a web-application on Websphere 8.5 using maven 3

I´m trying to make a Maven Project from an existing web application using JSF. The Project
should be deployed on Web Sphere 8.5.
Since i'm new to Web Sphere, don´t know how to build the "ear" Module, in order to be deployable on Web Sphere 8.5.
Does anyone know, where i can find further Information about deploying a web application on Web Sphere 8.5 using Maven 3.0.3?
Thanking you in anticipation,
Mosen
I've never worked with WebSphere Application Server 8.5; but in the days I was playing with IBM WAS 6.1 the WAS6 Maven plugin worked pretty well (it seems it works with WAS7 too). Here's a POM fragment from the plugin site that allows automatic EAR deployment:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>was6-maven-plugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<id>integration-test</id>
<phase>integration-test</phase>
<goals>
<goal>installApp</goal>
</goals>
</execution>
</executions>
<configuration>
<wasHome>${was61home}</wasHome>
<host>deploymentmanager.your.domain</host>
<username>admin</username>
<password>adminpassword</password>
<targetCluster>nameOfCluster</targetCluster>
<profileName>Dmgr01</profileName>
<conntype>SOAP</conntype>
<port>8879</port>
<verbose>true</verbose>
<updateExisting>false</updateExisting>
</configuration>
</plugin>
That plugin is for deployment and other administrative task, for EAR generation you can use the Maven EAR Plugin as described in 20InchMovement answer.
Hope this could helps:
<plugin>
<groupId>com.orctom.mojo</groupId>
<artifactId>was-maven-plugin</artifactId>
<version>1.0.8</version>
<executions>
<execution>
<id>deploy</id>
<phase>install</phase>
<goals>
<goal>deploy</goal>
</goals>
<configuration>
<wasHome>${env.WAS_HOME}</wasHome>
<applicationName>${project.build.finalName}</applicationName>
<host>${local or remote address}</host>
<server>server01</server>
<node>node01</node>
<virtualHost>default_host</virtualHost>
<verbose>true</verbose>
</configuration>
</execution>
</executions>
</plugin>
From https://github.com/orctom/was-maven-plugin
in order to package an *.ear, you don't need Websphere.
This can be accomplished with maven itself.
pom.xml:
<project>
...
<artifactId>YourApp</
<packaging>ear</packaging>
...
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ear-plugin</artifactId>
<configuration>
<modules>
<jarModule>
<groupId>${project.parent.groupId}</groupId>
<artifactId>configurationApp</artifactId>
</jarModule>
<ejbModule>
<groupId>${project.parent.groupId}</groupId>
<artifactId>AnEjbModule</artifactId>
</ejbModule>
</modules>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
...
</project>
Then you add your dependencies.
On command line go to your project and run mvn package.
Because of the package defined in you pom.xml, the ear will be created and can be found in the YourApp/target directory.
On the websphere admin console you can simply install the ear.
After login, goto:
Applications->Websphere enterprise applications and install a new application.
Select your YourApp.ear and go for easiness through the fast path to install the app.
The port to check is probably
yourServerName:9080/YourApp.
Good luck.
See http://code.google.com/p/websphere-maven-plugin/
Websphere Maven Plugin provides goals to:
deploy ear on websphere 7
start application
stop application
uninstall
require websphere application client.

Resources