Running main classes from a deployed artifact with maven - java

I don't get it. I've set up my pom.xml to use the Maven exec plugin so I can execute some of the classes in my project with the correct classpath, -D defines and -javaagent. So from a shell with the classes built in ./target/classes etc.. I can run the main() methods using
mvn exec:java -Dexec:mainClass=classWithAMainMethod
All good so far.
Now I want to ship my project(a jar artifact) and I still want to be able to use the configuration I've put in the pom.xml for running the classes with the correct arguments etc.. How do I do it? Is there some way of staying
mvn -artifactJar=MyArtifact.jar exec:java -Dexec:mainClass=classWithAMainMethod
when all I have is MyArtifact.jar(Or a maven repository with MyArtifact.jar in it)??
I've tried the following:
Get the jar with the dependency:get goal and unzip it. I can't do anything with it
as the pom.xml seems to end up in META-INF/maven in the artifact jar. Is there any way of using it?
Creating a dummy pom where I want to run my project with a single dependency on my projects artifact. I can then use exec:java to run the main classes but it's dosen't uses the configuration from my projects pom.
Thanks.

The AppAssembler plugin worked out quite well for me. I replaced the exec plugin config in my project's pom with something like this in the build section:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.2.2</version>
<configuration>
<repositoryLayout>flat</repositoryLayout>
<repositoryName>lib</repositoryName>
<extraJvmArguments>
-Djava.rmi.server.hostname=localhost
-javaagent:${spring.javaagent.jar}
</extraJvmArguments>
<programs>
<program>
<name>foo1</name>
<mainClass>net.foor.FooMain</mainClass>
</program>
...
</configuration>
</plugin>
In Eclipse I created an external tools launcher to run the resulting scripts from target/appassembler/bin
On the machine I wanted to deploy to(Assuming access to the internal Maven repository where my artifact+dependencies have been installed/deployed):
First use wget or mvn dependency:get to get a copy of my artifact jar.
Extract the pom. unzip -j artifact.jar */pom.xml*
Run mvn appassembler:assemble -DassembleDirectory=.
Move the artifact.jar into the ./lib directory
Set execute permissions on generated shell scripts in ./bin

Have you tried using something like onejar?
That sounds like what you're looking for.

Related

How to run Maven Checkstyle plugin on modified files only

I am running Maven Checkstyle plugin through pre-commit githook written in python (I think that the same question applies to running it directly from terminal).
The command is:
mvn checkstyle:checkstyle
However, I would like to run Maven Checkstyle only on files modified by git. For instance, I could run it once for each file. If I want to run it on a specific file, I may define the following pattern (I am not sure why do I need the pattern of stars and dashes in front):
mvn checkstyle:checkstyle -Dcheckstyle.includes=**\/*File.java
However, I am not able to pass file path and file name, for instance:
mvn checkstyle:checkstyle -Dcheckstyle.includes=src/main/java/File.java
Or, following the above mentioned pattern:
mvn checkstyle:checkstyle -Dcheckstyle.includes=**\/*src/main/java/File.java
I have tried many other combinations as well, but nothing works. I found this issue which is about the same thing, so I am wondering if someone has found a solution to this.
I have also read:
How to run maven checkstyle plugin on incremental code only
Is there a maven-git-checkstyle plugin that runs checkstyle goal on git staged files alone?
How to check style arbitrary list of java files from command line?
but they do not solve my problem.
There is an example here: github project of maven-checkstyle-plugin
Put a placeholder in pom and pass the parameter by maven command line.
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<includes>${checkstyle.includes}</includes>
</configuration>
Command line: mvn checkstyle:check "-Dcheckstyle.includes=**/File.java"

Spring boot app deploy to appengine from azure dev ops

I can make the Azure ops pipeline but my question is I have checkedin my code into repository where we should not checkin the application property file.
That means on the deployment time i should have to download the application property file from some secure place and build my spring boot app before i deploy into app engine right.
So, what i did so far is, I downloaded my application property file into azure agent at run time. I passed the property file into maven build command but it did not work out. [Note: I already searched a lot read a lot of answers and applied as well but nothing worked]
Command line I used:
mvn -f myapp-springboot-api/pom.xml
-Dspring-boot.run.jvmArguments="-Dspring.config.location=file:/home/username/application.properties"
clean package appengine:deploy
I also tried with
mvn -f myapp-springboot-api/pom.xml
--spring.config.location=file:/home/username/application.properties
clean package appengine:deploy
This also did not workout.
Also, I tried passing the whole property file location via pom.xml
pom.xml changes:
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>1.1.1.RELEASE</spring-cloud.version>
<property.file.location>${property.file.location}</property.file.location>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<version>1.0-alpha-1</version>
<configuration>
<files>
<file>${property.file.location}</file>
</files>
</configuration>
</plugins>
</build>
Than I tried to build with:
mvn -f myapp-springboot-api/pom.xml
-Dproperty.file.location="/home/username/application.properties" clean package appengine:deploy
Than also I was not able to load the define external property file.
Thanks in advance, please help your help is highly appreciated.
The commands you are using won't actually pass the external properties files to the application engine (As it exists on a different server) and would only be scoped to the running maven process that is packaging + deploying.
So if you have copied your property file onto the external agent before building I would just replace the default one you have checked into source control.
So your build steps would be for example:
Download property file
Overlay:
mv /home/username/application.properties myapp-springboot-api/src/main/resources/application.properties
Build + Deploy
mvn -f myapp-springboot-api/pom.xml clean package appengine:deploy
So now your compiled and deployed jar file would include your new properties file, an alternative that recently came out would be to use something like Azure App Configuration.
If you want to not have to do another command you could also use the Maven Resources Plugin to perform the copy for you.

Need to create Java JAR file and add it to Maven Dependency

I have a project downloaded from git. Here is the link to source code https://github.com/dwdyer/reportng, I have downloaded it and now I am trying to create a JAR file and then want to attach it to maven repository. When I compile it using mvn compile and mvn package, it gives me the same INFO message, and in my target folder there is a jar file is created. But only pom.xml and pom.properties are shown inside it, instead of whole hierarchy of compiled class files replaced with Java files
Maven is very picky about following a very specific folder layout in the given project (which you can override but it is not really intended to do so).
Instead you may want to just install the generated jar file directly in your local repository using the mvn install:install command.
If you want to script this, see Multiple install:install-file in a single pom.xml for instructions on how to create a pom.xml doing this.
First of all, you have to debug problem:
cd reportng/
mvn -e clean install
-e switch on errors' trace.
If everything ok, install will add jar just created jar file to your local repository.
Then it will be available as dependency to any project:
<dependency>
<groupId>org.uncommons</groupId>
<artifactId>reportng</artifactId>
<version>1.1.4</version>
</dependency>
By the way:
Jar is available in maven central, so referencing it as dependency, having compile time internet connection, will be enough.
This can be solved by changing the Maven strusture. Maven must contain src/main/java, whereas in the program it is src/java/main

Add JAudiotagger Library to Java on Windows 7

I am a (very) amateur programmer. I am using Groovy to edit MP3 file tags. Previously (about two years ago), I added the JAudiotagger class library to my Java installation using the detailed instructions given in the JAudiotagger readme file, and then called the required classes from my Groovy script. However, there is no readme file (that I can find) in the latest version of JAudiotagger, and I have so far failed to work out what to do.
Please can someone give me simple instructions on how to add JAudiotagger to Java, e.g. what files do I need to download, from where and what do I do with them.
I am running Windows 7.
All help gratefully appreciated.
The easiest way is to simply download the jar of jAutioTagger and put it in your classpath, so when the program launch, the classes in the jar should be accessible: java classpath
Now if you want a more generic way of handling dependencies altogether, i suggest you start reading about maven (which a build tool with dependecny managment).
You can also use gradle which looks more for groovy but I do not know about it.
As for starting a new project with maven it requires some steps. Here is a lightweight tutorial:
Create a maven project
Add the desired dependencies in your pom.xml
Build the project with libraries embedded
Run the program
Create a maven project
Type in the following command in your command line:
mvn archetype:generate -DarchetypeGroupId=org.apache.maven.archetypes -DarchetypeArtifactId=maven-archetype-quickstart -DarchetypeVersion=5-SNAPSHOT
It will ask you some questions like the group id and the artifact id as well as the project name.
Add the desired dependencies in your pom.xml
The pom.xml is where you configure your project, like build things and dependencies, to have audiotagger as a dependency add the following:
<dependency>
<groupId>org.jaudiotagger</groupId>
<artifactId>jaudiotagger</artifactId>
<version>2.0.1</version>
</dependency>
This will add jaudiotagger to the dependencies of your project, you can add groovy as well. You'll also need dependencies too groovy and the groovy compiler.
Hint: I use sonatype to find dependencies
Build the project with libraries embedded
Now to build your project with maven. Just type the following command:
mvn clean install
but this will not add the dependencies to your jar, so you need to embedd them by adding a plugin to your pom.xml configuration:
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>be.phury.audiotagger.Audiotagger</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
You can now generate a jar with dependencies by typing in the command line:
mvn clean install assembly:single
Run the program
Just run the jar
Hope this helps
If you do not want to go through Maven/Gradle, you could also use the #Grapes annotation:
#Grapes(
#Grab(group='org.jaudiotagger', module='jaudiotagger', version='2.0.1')
)
in top of your Groovy script, that would download your dependencies whereever you start your script. I found the dependency http://mvnrepository.com/artifact/org.jaudiotagger/jaudiotagger/2.0.1 - they even make the full #Grapes notation for you.

dependency not found at runtime maven

I'm new to maven and somewhat new to java. Tried google and related sources, but I didn't find one which resembled my situation.
Right now, I have maven project X and Y. X can be seen as a shared library with some utilities, Y is a simple JFrame with a "hello world" printed and a call to a static method in X.
I do a "run as maven install" on project X, I get a "build successful". I add project X as dependency in project Y (using the pom-editor in Eclipse, browsing the repository and locating it). I do a "run as maven package" on project Y, I get a "build successful". Upon running project Y either via java -jar or inspect the produced jar, project X is missing everywhere and I get a fancy class not found exception. Eclipse finds it and there are no compile errors in the source editor.
Why is it only working in the Eclipse editor and not as jar?
POM:
<dependency>
<groupId>com.company.deployment.shared</groupId>
<artifactId>com.company.deployment.shared</artifactId>
<version>0.0.1-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
Maven doesn't produce a combined JAR file for you. What Eclipse is doing is looking at the Maven configuration and adding all the required classes / jars to your classpath for you when it runs.
If you want to run your program from the command-line, you will need to add all the JARs manually to your classpath.
Alternatively, you could run your program directly from Maven which should set up all your dependencies. There are a number of options depending on what you want to do, i.e. if it's an application which is meant to be run by an end-user you could look into the one-jar Maven plugin.
I recommend that you take a look at the Maven shade plugin. This produces an "uber-jar" comprising your project and all of its dependencies. It can also do other things such as setting the entry point class to make your JAR file an executable JAR.
You may also find exec-maven-plugin helpful
mvn exec:java -Dexec.mainClass="com.example.Main" [-Dexec.args="argument1"] ...
mvn exec:exec -Dexec.executable="maven" [-Dexec.workingdir="/tmp"] -Dexec.args="-X myproject:dist"
If your client can not download dependencies from maven m2 repo on the fly like behind firewall or no internet connection, then you also need to package the dependencies using maven-dependency-plugin to copy all dependencies and maven-assembly-plugin to assemble dependencies
It doesn't work because Maven resolves dependencies when building your project, but doesn't put all the dependencies magically in your jar. You're supposed to run your app with all its dependencies in the classpath:
java -classpath X.jar;Y.jar com.foo.bar.Main
Or you have to customize the maven jar plugin in order to create an executable jar, as described here. And you may also use the maven assemby plugin to copy all your Y project's dependencies to the target directory, next to the generated Y.jar.
The artifact produced in project Y contains only build results in project Y only, not including its dependencies.
If you want to build a JAR in Y, which u can execute directly, you can consider using assembly plugin.
For example, the easiest way to build a uber-jar for project Y:
<project>
...
<build>
...
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2.1</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-all-in-one-jar</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
...
</project>
Apart from a normal artifact, an assembly which contains classes etc from dependencies will be created, which is suitable to be executed by java -jar
visit http://maven.apache.org/plugins/maven-assembly-plugin/ for more sophisticated usage.
Phil Sacre already explained the basic problem well (there basically is just no information on where to find the X.jar embedded in your Y.jar).
Additionally you can also look at the appassembler-maven-plugin (which can e.g. generate launch scripts for your Y project that already have the right classpath set) and/or the exec-maven-plugin (which you can use to e.g. directly launch Y with the right classpath using maven).

Categories

Resources