Where should I track my Java EE web app version - java

In a web application where should I mention and track the version number?
I'm using maven, which has version element in pom.xml. However, I cannot trace back that version number after packaging as war. Though, that version number is stored in the filename as applicationname-1.0.1.war. I wanted to know if it stores somewhere within the package or any way to do it?

Use the maven archive plugin to store it in the WARs Manifest.

If stamping the version in the MANIFEST is good enough for your needs then you'll want to configure the maven-war-plugin something like this:
<build>
<pluginManagement>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
<manifestEntries>
<Build-Repository-Rev>${SVN_REVISION}</Build-Repository-Rev>
<Build-Time>${maven.build.timestamp}</Build-Time>
</manifestEntries>
</archive>
</configuration>
</plugin>
...
The children of the manifestEntries element can be anything and will create entries with given name. In this example, there would be entries of "Build-Repository-Rev" and "Build-Time" created using the "SVN_REVISION" environment variable and "maven.build.timestamp" property in addition to the entries created by the "addDefaultImplementationEntries" which would include an "Implementation-Version" entry set from ${project.version}.

Related

quarkus-maven-plugin does not add implementation-entries to MANIFEST

I want to read the current artifact version of my maven-project inside my of a RESTful service. My code is written in JAX-RS (Quarkus).
I am using a the following pom.xml snippet:
<plugin>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.version}</version>
<configuration>
<archive>
<manifest>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
<executions>
<execution>
<goals>
<goal>build</goal>
</goals>
</execution>
</executions>
</plugin>
I read the version with the following java snippet:
String vendor = getClass().getPackage().getImplementationVendor();
It seems to me that the quarkus-maven-plugin is ignoring that line since maven-jar-plugin is working perfectly fine (I used this in a different project):
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
I do not have a really profound knowledge of maven and quarkus yet.
Am I making a mistake setting up the quarkus-maven-plugin?
Is there a workaround which does not include reading directly from the pom.xml?
Thank you for helping me.
EDIT:
I will mark this thread as "answered" as soon as the following issue
is resolved (opend by #Guillaume Smet):
https://github.com/quarkusio/quarkus/issues/5023
EDIT:
Issue is resolved as of today.
https://github.com/quarkusio/quarkus/issues/5100
Adding addDefaultImplementationEntries won't help, we build the jar ourselves and we don't push any of this information to it.
I created https://github.com/quarkusio/quarkus/issues/5023 for this.
For the time being, you can either push the information to the manifest yourselves (we enhance it if you have an existing one) or inject the values we derive from the POM files in your REST resources with:
#ConfigProperty(name = "quarkus.application.name")
String name;
#ConfigProperty(name = "quarkus.application.version")
String version;

PDFBox with Maven - java.lang.NoClassDefFoundError

When installing PDFBox with Maven, it places the libraries in the ~/.m2/repository directory.
My program complies fine with mvn package.
When I try to run it with
java -cp target/java-project-1.0-SNAPSHOT.jar com.example.sub.App
then I get
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/pdfbox/pdmodel/PDDocument
Should I also be specifying the libraries in ~/.m2/repository as part of the classpath? This seems a bit too tedious to do it this way. What is the recommended way to specify the classpath of my PDFBox library while using the library location(s) of Maven?
I wasn't able to find a nice solution with leaving the JAR files in ~/.m2, so the answer below is a workaround based on some other answers. I will be including more clarification though for those who are new to both PDFBox and maven as I am.
1) Add the following to your pom.xml file. If you already have a <build> and <plugins> section, just add the <plugin> section below to that. Otherwise you may need to add the whole code below within the <project> element:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>**REPLACE THIS WITH THE FULL URI OF YOUR MAIN CLASS**</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-my-jar-with-dependencies</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
2) Make sure that you replace the text in the <mainClass> element to match the situation. For example, if your main() method is located in an App class in App.js, and your package name is com.example.sub. Then the above element should read:
<mainClass>com.example.sub.App</mainClass>
3) To compile your app, run mvn package
Note: I have seen some references online using mvn clean compile assembly:single instead of mvn package. I am not sure what the purpose of this is when mvn package seems to run just fine for me.
This will take your project and all of your dependencies and create a single JAR file in the target directory called something like this:
java-project-1.0-SNAPSHOT-jar-with-dependencies.jar
4) To run the project you can do this:
java -cp target/java-project-1.0-SNAPSHOT-jar-with-dependencies.jar com.example.sub.App
Make sure that you modify the above line to it your situation. In other words you may need to change both the name of the jar file and the name of the URI for your main class.

Netbeans 8.2 and maven - no main manifest attribute error

i am using netbeans 8.2 to create a simple java project. i've chosen Maven-Java Application. I've created a simple hello world java class. I've selected the java class as the main class from Properties -> Run and if i run the project from Netbeans, it print the hello world. After that, i do "Clean" and "Build with dependencies" the editor create a target folder with the jar file. When i go to that folder and execute "java -jar XXX.jar", i get the no main manifest attribute error. Do I have to manually update the POM.xml file? Am I missing a step?
I am answering my own question.
Apparently you have to manually update the pom.xml file. I've added the dependency for maven-jar-plugin and added below section to the pom.xml file.
<build>
<plugins>
<plugin>
<!-- Build an executable JAR -->
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.mypackage.XXX</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>

Compiling only selected files in Maven

I want to compile only selected files or directories (including subdirectories) within source directory. I was pretty sure I can do this using <includes> of maven-compiler-plugin's configuration, but it seems to not work as I expect since it still compiles all classes into target/classes. What is really strange, Maven output suggest that the setting actually does its work, because with:
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.5.1</version>
<configuration>
<includes>
<include>com/example/dao/bean/*.java</include>
</includes>
</configuration>
</plugin>
I have:
[INFO] Compiling 1 source file to c:\Projects\test\target\classes
but with no compiler's configuration I have:
[INFO] Compiling 14 source file to c:\Projects\test\target\classes
In both cases however, all 14 classes are compiled into target/classes as I mentioned. Can you explain that or suggest another solution to compile only selected files?
Simple app with 3 classes.
com/company/Obj1.java
com/company/Obj2.java
com/company/inner/Obj3.java
build in pom.xml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.0.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<includes>
<include>com/company/inner/*.java</include>
</includes>
</configuration>
</plugin>
</plugins>
</build>
result: 1 class is compiled.
And any combination of includes is working well
or you mean something else?
I have faced a similar situation. We needed to hot swap only modified files to our remote docker container in order to improve changes-deploy time. This is how we solved it.
Add includes option in build plugin with command line argument.
Note since we wanted to add multiple files, so we have used includes and not include
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<compilerVersion>1.8</compilerVersion>
<source>1.8</source>
<target>1.8</target>
<includes>${changed.classes}</includes>
</configuration>
</plugin>
Now run compile phase with argument, example:
mvn compile -Dchanged.classes=com/demo/ClassA.java,com/demo/ClassB.java,com/demo2/*
maven-compiler-plugin using Ant-like inclusion/exclusion notation.
You can see examples in Ant documentation Ant FileSet Type
If you are want include only files from one directory, you need write it like you did:
<include>com/example/dao/bean/*.java</include>
To include also subdirectories from path, it will be:
<include>com/example/dao/bean/**/*.java</include>
I had no difficulty including or excluding files for compilation with maven compiler plugin 2.5.1. Here is the dummy project I used for the purpose. Perhaps the include pattern that you use is different.

Maven - EJB plugin in parent pom

I've just been asked to work on an existing Java EE web project.
The project contains a lot of modules, some EJB packaged in a EAR and a web part inside a WAR.
What is bothering me is that you actually need 1h30 to compile the whole stuff.
And I found this inside the parent POM betwen the plugin managment part :
<plugin>
<artifactId>maven-ejb-plugin</artifactId>
<configuration>
<ejbVersion>3.0</ejbVersion>
<generateClient>true</generateClient>
<clientIncludes>
<!-- Includes only service interface and business delegate. -->
<clientInclude>**/*Service.class</clientInclude>
<clientInclude>**/*Delegate.class</clientInclude>
<clientInclude>**/ejb/*EJBRemote.class</clientInclude>
</clientIncludes>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
<addDefaultSpecificationEntries>true</addDefaultSpecificationEntries>
</manifest>
<manifestEntries>
<Build-Time>${timestamp}</Build-Time>
<Implementation-URL>${project.url}</Implementation-URL>
</manifestEntries>
</archive>
</configuration>
</plugin>
Doesn't this means that every module is being "parsed" by the EJB plugin?
even non-ejb modules?
Thanks.
ps : the parent pom also have some dependancies that also are inside the modules' pom.
I totally forgot this : I found the solution and then the project "only" needed 15 minutes to be compile.
The java version needed to be upgraded, from what I remember there is some kind of bug with maven and java 1.6 version xxxxx.
At the time upgrading to the lastest version of java 1.6 solved the problem (or it was 1.5 I don't remember).

Categories