How to exclude unwanted JARs from exported WAR - java

I'm using maven to build my Spring Dynamic Web Project. I got recommendations from my security team to remove certain JARs citing some sort of vulnerabilities. I have manually removed those JARs from by WEB-INF/lib/ everything is working for me.
But I would like to automatically remove those JARS at the time of exporting WAR file.
I've tried below
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<warSourceExcludes>WEB-INF/lib/jstl-1.2.jar</warSourceExcludes>
</configuration>
</plugin>
</plugins>
I tried packagingExcludes in the place of warSourceExcludes but no luck. And I tried the different version of maven-war-plugin.

Related

IntelliJ IDE 2017.3.2 Maven Project packagingexcludes

I have a maven project that is going out to tomcat using a exploded war build in development. I have the following entry in my pom to exclude certain files for any non development environments:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<warSourceDirectory>web</warSourceDirectory>
<failOnMissingWebXml>true</failOnMissingWebXml>
<webXml>web/WEB-INF/web.xml</webXml>
<packagingExcludes>
WEB-INF/classes/application.properties,
WEB-INF/classes/proxool.xml,
WEB-INF/classes/log4j.properties,
WEB-INF/classes/wetemplates/**
</packagingExcludes>
</configuration>
</plugin>
The packaging excludes are being used by intellij and excluded from my local development build and breaking it. I have been having to comment this block out in development for the environment to function correctly. How can I resolve this so that these are not excluded in my development environment?
You can use maven profiles to configure the build in such way that the Intellij build will use one given profile and the Maven/external build will use another profile.
Take a look at here: http://maven.apache.org/guides/introduction/introduction-to-profiles.html

tomcat-maven-plugin with multiple modules building one war only

I try to build a web application based on multiple maven modules. One of the modules is called "web" and is solely responsible to package a war which should be deployed to a tomcat using the tomcat7-maven-plugin. I have following modules defined in my parent.pom:
common
persistence
persistence-embedded
service
rest
web
All of them are combined into one web-application-war, the web module has set packaging to war. The problem is, that my war file is deployed for each submodule (and the main-parent-module) over and over again when I run mvn tomcat7:redeploy, which leads to 7 deployments. Apparently, this is not how it should be. The tomcat7-maven-plugin configuration currently looks like this:
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<ignorePackaging>true</ignorePackaging>
<url>http://localhost:8080/manager/text</url>
<server>tomcatServer</server>
<path>/webapp</path>
<warFile> /home/username/dev/maven-multimodule-example/web/target/maven-multimodule-example-1.0-SNAPSHOT.war</warFile>
<username>admin</username>
<password>password</password>
</configuration>
</plugin>
As you can see, I need to specify the warFile (which is not a solution but rather a hack, because I can't use ${project.basedir} which would lead to the submodule-dir) to make it work.
However, if I run the web application with mvn tomcat7:run, it looks quite good, because the other non-war-building modules are skipped by the plugin.
How can I configure the plugin the right way to deploy the war file only once?
Every configuration within the <build> section of a parent POM will be inherited and thus executed in all child modules. So if you want to deploy only once, add it to only one POM (e.g. the web POM).
Thanks to dunni's help I noticed my missunderstanding of how multimodule projects are built. Now I've placed the plugin configuration in the web module and added an execution, bound to the install phase so that I can rebuild the whole project and get it deployed to my tomcat. Obviously maven takes care of the right execution order of the modules.
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<url>http://localhost:8080/manager/text</url>
<server>tomcatServer</server>
<path>/webapp</path>
<warFile>${project.basedir}/target/${project.parent.artifactId}-${project.parent.version}.war</warFile>
<username>admin</username>
<password>password</password>
</configuration>
<executions>
<execution>
<id>redeployafterinstall</id>
<phase>install</phase>
<goals>
<goal>redeploy</goal>
</goals>
</execution>
</executions>
</plugin>

Obfuscating WAR file with Proguard

I want to obfuscate my web application built as WAR archive, as this sensitive application in first time deployed outside our data center. I tried to use the Proguard GUI tool to obfuscate the input war, with all the service jar required for the UI application, with other external dependencies. Though the Proguard runs successfully with some warnings, ex., duplicate definition of library class [javax.servlet.UnavailableException], the output war contains no classes, but has lib with the library jars and web.xml files. Any steps I mess? Any right document on this? I would appreciate if anyone can provide the right document or steps to successfully obfuscate a WAR file with dependent project (a .jar file) and other external jar files (that needs no obfuscation).
you wouldn't obfuscate a war but rather the jars your using. What you can do here is setup your project so the project that makes up the war - configuration xml, WEB-INF content, resources and the web content and servlet definitions and put your java in a library project. Obfuscate the library project and use those obfuscated jars in your web project.
That's what I do, hope it helps.
Protector4j is the best solution to obfuscate the war file, due to graphic user interface its too easy to use and their eclipse plugin is also available.
You will download it from this link
https://doc.protector4j.com/protect-tomcat-web-app
I have done the same way. I used the below url for code obfuscation and i am successful.
http://bratonfire.blogspot.com/2012/01/war-file-obfuscation-using-proguard.html
I created a new folder and redirected output of classes to this folder. But the strange thing is that i am able to see the .java and .class files in the two locations. I am also worried about recreating a war file. can someone mention the clear and detailed steps.
Thanks,
Rahul
We also have the same issue and need to obfuscate all classes packaged in war file.Here is the approach that I followed.
Firstly we need to set order of plugins **(compiler, proguard, war)**declared in pom.xml file as below.
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.0.14</version>
<configuration>
</configuration>
<executions>
<execution>
<!-- Dont worry about compiler error. For first time, change this value to package so that plugin installs successfully. -->
<phase>process-classes</phase>
<goals>
<goal>proguard</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard-base</artifactId>
<version>1.0</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<warName>mfs-transaction-management</warName>
<warSourceDirectory>WebContent</warSourceDirectory>
<failOnMissingWebXml>false</failOnMissingWebXml>
<!-- Exclude your default packages from war packaging. Do not include "**" in double quotes in actual code -->
<packagingExcludes>
WEB-INF/classes/com/package/mypackage1/"**",
WEB-INF/classes/com/package/mypackage2/"**",
</packagingExcludes>
<webResources>
<webResource>
<directory>${project.build.directory}/proguardClasses</directory>
<targetPath>WEB-INF/classes</targetPath>
</webResource>
</webResources>
</configuration>
</plugin>
</plugins>`
Then create a file proguard.conf under the root of your project at the same level where pom.xml is placed.
Add your own configuration regarding proguard in the file and the add below two lines in this file to tell input and output folder to proguard plugin.
You need to set paths according to your project structure in these lines
-injars 'C:\Users\Rajdeep\git\dfs-core\mfs-transaction-management\target\classes'
-outjars 'C:\Users\Rajdeep\git\dfs-core\mfs-transaction-management\target\proguardClasses'
Apart from this you need to install proguard-base manually in maven repository using mvn install command.
Provide your own groupid, artifact and version and made same changes to pom.
It is proguard.jar found under proguard6.0.3\lib folder when you download proguard manually.
I think everything will be ok and now when you run mvn clean package, your war file should included obfuscated class files.
Use Proguard GUI to obfuscate war files.
Once you run proguardgu.bat or proguardgui.sh file from bin folder of your proguard directory. You can select wars by clicking Input/output menu.

WAR bundles SNAPSHOT JARs with timestamps

I have this multi module project setup which uses Webstart and I need to bundle the WAR with SNAPSHOT JARs. When the JARs are bundled into the WAR, they are appended with a timestamp instead of the actual name. This is causing issues during their download.
Expected - ABC-1.0-SNAPSHOT.jar
Actual - ABC-1.0-20141002.211448-2.jar
Env:
OS: Unix
Maven: 3.2.1
JDK: 1.7
I have already tried useUniqueVersions=false by defining a maven-war-plugin and setting this in the manifest configuration.
My webstart config:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>webstart-maven-plugin</artifactId>
<version>1.0-beta-6</version>
<executions>
<execution>
<phase>process-resources</phase>
<goals>
<goal>jnlp-download-servlet</goal>
</goals>
</execution>
</executions>
<configuration>
<outputDirectoryName>.</outputDirectoryName>
<excludeTransitive>true</excludeTransitive>
<commonJarResources>
<jarResource>
...
</jarResource>
</commonJarResources>
<jnlpFiles>
<jnlpFile>
<templateFilename>JNLP-INF/APPLICATION_TEMPLATE.JNLP</templateFilename>
<outputFilename>client.jnlp</outputFilename>
<jarResources>
<jarResource>
...
</jarResource>
</jarResources>
</jnlpFile>
</jnlpFiles>
<sign>
...
</sign>
<outputJarVersions>false</outputJarVersions>
</configuration>
Appreciate any inputs.
UPDATE
Adding details about the WAR plugin I added
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
</plugin>
The behavior continues. I read that maven 3 uses a unique snapshot system. But I am trying to work my way around it.
Also tried the following without any luck
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.4</version>
<configuration>
<outputFileNameMapping>${artifact.artifactId}-${artifact.baseVersion}.${artifact.extension}</outputFileNameMapping>
</configuration>
</plugin>
The creators of the maven-webstart-plugin have accidentally inverted the meaning of the flag useUniqueVersions. When set to true it produces jars of the form -SNAPSHOT.jar and when set to false (the default) it produces jars of the form --.jar
I found that setting the useUniqueVersions flag to true in the maven pom configuration produced my desired results.
I needed it like this because when deployed with the datestamp version of the snapshots when trying to launch it I was getting a "Resource not found" error when it tried to get the snapshot jar it was trying to launch. Presumably this means that the servlet code itself is not set up to handle the different naming on disk, despite the fact that the specific datestamp version number does end up in the jnlp itself.

How maven jar project works when it is packaged to jar?

I am new to maven. I have created a maven project which will be packaged to JAR. I did clean package then jar is created. When i extracted the same jar, i could not see any dependencies (jars) i added in pom.xml inside the packaged jar. If i give this jar to third party clients how will the code work without any dependent jars ? Please help me how maven manages the jars?
Thanks!
Maven handles dependencies based on how you configure the dependency plugin.
See this reference for a simple example of how to do this.
In this example, the following code configures where your dependencies will end up:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<includeGroupIds>log4j</includeGroupIds>
<outputDirectory>${project.build.directory}/dependency-jars/</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Then this code sets up the classpath for your main jar, which will allow anyone running it to find these dependencies
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.mkyong.core.App</mainClass>
<classpathPrefix>dependency-jars/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
Your other option would be to create a single jar, with all dependencies included, by following this example here
You could distribute the jar and the POM file if you want to try and provide your users with the files in that manner, but they'd need to be able to access your Maven repository where those dependencies are kept.
Core maven doesn't handle this. Maven is a build tool, its work is to build an artifact (a jar in your case). Dependencies you define in your module's pom.xml file are needed to get the code compiled. You'll need maven plugins to do so.
Now, you're asking not about the build, but the distribution of your compiled binaries.
If I understand it should be a lot of jars (your and your dependencies). Alternatively you may distribute the code as a jar + dependencies inside.
Example:
A first case:
If your code resides in module A (say, the code is in packages org.a.*) and depends on some thirdparty (say, log4j, whose classes reside in org.apache.log4j) than you can expect that you jar will only contain the classes of module a and you expect that the log4j will be added by the user of your module automatically (The first case).
A second case:
module a.jar will contain both org.a.* and org.apache.log4j.* classes, everything in the same module.
In general the first approach is more "healthy" and in this case you shouldn't do anything in maven. Maybe your distribution tool/documentation should contain this information.
If someone uses the module a in his/her code like a thirdparty (if you develop a framework or something) and if his/her project is mavenized, than the fact you've defined a dependency on log4j will make the maven to download the log4j as well as your a.jar (In maven notation, this is called "transitive dependencies").
If you're interested in the second case (this can be relevant if you define some "client application", like "jndi client for some server" for example) you might want to take a look on Maven shade plugin
Beware this can lead to dependency hell (what if the application that uses your client also makes use of log4j? what if the log4j-s are of different version)/
Bottom line, you probably want the first approach, think twice before you decide the second approach :)
One more tip, if you just want to download all the dependencies of your module "a" you might want to use maven dependency plugin - type the following in the command prompt
mvn dependency:copy-dependencies
and you'll find all the dependencies in target/dependencies folder
Hope this helps and happy mavening
The simplest solution to the problem is to use the maven-assembly-plugin which can create such jar with dependencies like the following:
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>distro-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Afterwards you can distribute the created jar xyz-1.0-jar-with-dependencies which contains the defined dependencies.
If you need more control on how the resulting artifact is created or if some files needed to be overwritten etc. you might take a deeper look into maven-shade-plugin

Categories