Packaging war file with maven - java

I thought that, if my project is named my-web-application, than when I call mvn clean install maven first compiles to target\my-web-application-1.0 folder and than "zips" that folder to my-web-application-1.0.war...
But as I found recently it's not how it (maybe just with default settings) works.
I'm using some 3rd party components and I'd like to modify some styles (.css) and behavior (.js) for those components, so I simply replace content in dependency jar with my modification using
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<plugin>
execution example follows (it zips org folder to componentToModify.jar)
<execution>
<id>fix</id>
<phase>package</phase>
<configuration>
<executable>jar</executable>
<workingDirectory>${basedir}</workingDirectory>
<arguments>
<argument>-uvf</argument>
<argument>target/${project.artifactId}-${project.version}/WEB-INF/lib/componentToModify.jar</argument>
<argument>org</argument>
</arguments>
</configuration>
<goals>
<goal>exec</goal>
</goals>
</execution>
what correctly modifies the componentToModify.jar in the target\my-web-application-1.0, but final war doesn't contain the modifications. It seems that libs are zipped to war from local repository.
Is there some reason for such behavior and can I change it somehow?

Not completely sure but would using an Overlay help here?
http://maven.apache.org/plugins/maven-war-plugin/overlays.html
If all else fails, you may just want to modify the 3rd party application and produce your own jar with your changes.

Related

Java Documentation from Vscode

Hey I am using the Spring tool suite for Vscode It's working great but there is one thing I am missing like in other IDE's you can view the documentation for a specific Annotation or method.
for example:
If I try to view the documentation for any annotation in intellij it shows the documentation properly, but if i try to do the same on vscode it shows up like this:
You can enable the setting java.maven.downloadSources.
Then each time you opened a class file, if the source jar does not exist locally, the extension will trigger a download task for that source jar. After that, next time you open that class file, you can see the source.
This message says that VS Code couldn't find the JAR archive that contains source files for this class. These JARs usually are called XYZ-sources.jar. You need to download an archive like that manually or use the Maven plugin that can download it for you.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>src-dependencies</id>
<phase>package</phase>
<goals>
<goal>sources</goal>
</goals>
<configuration>
<silent>true</silent>
</configuration>
</execution>
</executions>
</plugin>
Then, if you have downloaded JAR archive you need to press Right Mouse Button -> Attach Source.

How to create an additional JAR for a specific folder with maven

I have a maven project, I need to generate three separate jars
one for the main application (default)
one for the source code (maven-source-plugin)
and one for my app documentation which reside in target/docs
Question: How can I create a jar containing only the target/docs folder?
You could add the following to your maven pom.xml file, build/plugins section:
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<configuration>
<classifier>docs</classifier>
<classesDirectory>${project.build.directory}/docs</classesDirectory>
<includes>**/*</includes>
</configuration>
<id>pack-docs</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
Which is basically:
Using the maven-jar-plugin, jar goal to pack a new artefact for the project
Adding (or attaching) it as a classifier (docs suffix appended to the normal convention for project artefacts, e.g. artifactId-version.jar)
Setting the target\docs as source of files, using the standard ${project.build.directory} property instead of target (which is its value by default)
Running
mvn clean package
You would then have as part of the output
The jar file normally created, e.g. sample-project-1.0.0-SNAPSHOT.jar
The new docs file, e.g. sample-project-1.0.0-SNAPSHOT-docs.jar

Maven: Replace token in source file before compilation

I want to replace a token #NAME# in a source file (in my case *.java) before compilation.
I try to use google replacer plugin but I am open for anything which will help me.
1.pom.xml
The pom file look like this
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.3</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<includes>
<include>src/main/java/com/test/sample/File.java</include>
</includes>
<replacements>
<replacement>
<token>#NAME#</token>
<value>New content</value>
</replacement>
</replacements>
</configuration>
</plugin>
But after I run mvn package the output is:
--- replacer:1.5.3:replace (default) # MyProject --- [INFO] Replacement run on 0 file.
Because there is no error I do not know what I have done wrong.
Maybe:
Defined phase is wrong
Defined include is wrong
...
Greetings!
I think there are two options.
If you keep using the plugin I think you need to add the ${basedir} to the include statement:
<include>${basedir}/src/main/java/com/test/sample/File.java</include>
If you dont want to modify the file in src/main but filter the file and add that one to the build you can use the standard resource filtering and the buildhelper plugin to add those "generated sources" to the build.
So step one would be using resource filtering to copy the file: http://maven.apache.org/plugins/maven-resources-plugin/examples/filter.html
And then use the http://www.mojohaus.org/build-helper-maven-plugin/ to add those sources to the build.
Some IDEs (IntelliJ) will recognize /target/genereated-sources automatically if you keep using that folder (its not standard but very common). If you search for "maven" and "generated-sources" you will find quite some tutorials.
Hope this helps :)
While this is something you usually should not do in the first place, sometimes you have no choice (in my case it was "converting" an old project to Maven with changing as little of the code as possible). The above somehow did not work (while I could replace a placeholder in the source file and add the generated-sources folder to be compiled, it complained about duplicate source files).
Then I found an easier way by using the templating-maven-plugin as described here http://www.mojohaus.org/templating-maven-plugin/examples/source-filtering.html:
Put the file with the placeholder in the folder /src/main/java-templates. Excerpt from my source code:
public static final String APPLICATION_VERSION = "r${project.version}";
Add the following to your pom's plugins section:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>templating-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<id>filter-src</id>
<goals>
<goal>filter-sources</goal>
</goals>
</execution>
</executions>
</plugin>

Can Maven re-sign dependencies?

I'm using maven-jarsigner-plugin to sign a shaded uber-jar of mine. I do need to distribute some dependencies in their own jars though, and want to take those jars from a Maven repo, clear them of any existing signatures, and sign them with my own certificate.
Are there any Maven plugins that do this, or would i involve some Ant plugin hackery?
Turns out maven-jarsigner-plugin can re-sign existing jars using it's removeExistingSignatures config element. So simple!
I use maven-dependency-plugin to copy artifacts into a .war project in the generate-resources phase, then sign them in the process-resources phase.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.8</version>
<executions>
<execution>
<id>copy</id>
<phase>generate-resources</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.lwjgl.lwjgl</groupId>
<artifactId>lwjgl-platform</artifactId>
<version>2.9.0</version>
<classifier>natives-osx</classifier>
<type>jar</type>
<overWrite>true</overWrite>
<outputDirectory>src/main/webapp/</outputDirectory>
<destFileName>lwjgl-platform-natives-osx.jar</destFileName>
</artifactItem>
</artifactItems>
<outputDirectory>src/main/webapp</outputDirectory>
<overWriteReleases>true</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jarsigner-plugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<id>sign</id>
<phase>process-resources</phase>
<goals>
<goal>sign</goal>
</goals>
</execution>
</executions>
<configuration>
<keystore>${basedir}/path/to/my.keystore</keystore>
<alias>alias</alias>
<storepass>password</storepass>
<keypass>password</keypass>
<verbose>true</verbose>
<archiveDirectory>src/main/webapp/</archiveDirectory>
<processMainArtifact>false</processMainArtifact>
<removeExistingSignatures>true</removeExistingSignatures>
</configuration>
</plugin>
I know it is not a really good answer, but I would try a solution in these steps:
copy dependencies by maven-dependency-plugin
antrun: <unzip> them, strip everything from /META-INF directory except MANIFEST.MF, <jar> again and sign them again by using <jarsign> ant task.
The main problem I have found since I work with maven (quite recently I admit) is that it makes you go through its predefined pipeline, and this kind of things (which is more common than it seems) will make you need some ant hackery as you call it ;)
Never used it, but it seems the webstart-maven-plugin can unsign and sign jars.
http://mojo.codehaus.org/webstart/webstart-maven-plugin/unsign-mojo.html
Hope this help.
Using maven:
Create an empty maven jar module per jar that you want to resign, do a maven dependency:unpack of one of the jars, filtering the signature files and copying the files to src/main/java.
Then sign the jar with maven-jarsigned-plugin, the result will be a jar containing the same classes.
An alternative non-maven based:
The above way does not scale well, it would probably be simpler to create a script that follows these steps.
The simplest way to do it would be:
Instead of resigning the jars, consider registering the public key of the signer in your maven repository, meaning you trust the person that created these jars and accept any jars coming from them.
The truth is you already trust them since you are using their code and resigning it, so it would be simpler to configure the repository to accept their signature, in the same way that the repository was already configured by someone to accept your signature.
The repository is linked to a key store containing the public keys of the accepted jar signers, it would be a matter of asking the team that handles the repository to add one more key to their list of trusted signers, they would know how to do that for sure.

maven properties-maven-plugin doesn't work when deploying artifact to Nexus

I am using properties-maven-plugin to read a external property file under root dir to maintain the version of parent module since there are quite a number of sub-modules in my project and the dependency tree is kinda deep.
It works fine when I build locally and install the artifacts into local repo but got the 401 error when I try to use "mvn clean deploy" to publish them to Nexus. I am pretty sure this is caused by the ineligible artifact name(releaseurl/{external.version}), external.version is supposed to be the property read from the external file. However, it ended up not being read and it just worked fine when I explicitly declare the version in the project.parent.version tag. Any thoughts or workaround? or even how you handle the version control when trying to use same version for parent and child in all the modules when dealing with a multi-module porject.
The maven pom for the plugin is as below, I saw some comments online regarding the phase, not sure if it will work if change initialize to something else:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>properties-maven-plugin</artifactId>
<executions>
<execution>
<phase>initialize</phase>
<goals>
<goal>read-project-properties</goal>
</goals>
<configuration>
<files>
<file>external-file.properties</file>
</files>
</configuration>
</execution>
</executions>
</plugin>

Categories

Resources