How to Include a SINGLE dependency into a jar using maven and fatjar plugin - maven

I feel a bit stupid about this question but i can't figure out how to add a SINGLE dependency (jdom.jar) into another jar.
Context: We developed a simple plug-in for our application, this plug-in have many dependency. We were using fatjar to include jdom.jar into it. I am trying to fix a bug in this plug-in, so i decided to "maven-ize" it at the same time. (We just switched to maven) This plug-in is loaded on the runtime so the only dependencies we want packaged with it is the jdom.jar.
Problem: I found that there is a maven fatjar plug-in! Unfortunately i could not find any documentation and this maven plug-in add EVERY dependency into the ouput jar. After many try i decided to give up on this fatjar plug-in and searched for another one. I found one-jar , shade but after a quick read on them they look like they add every dependency.
Question: what would be a simple way to add only jdom.jar into my plug-in jar like this:
-MyPlug-in.jar
|
|-src
|-main
|-java
|-*.java
|-jdom.jar
Also I don't want to alter the manifest or the output jar filename
Thank a lots for your time.

There was no answer here regarding how to use maven to include one single jar-file with the maven-shader-plugin. It took me some time to figure out how to actually do that. Here is a snippet to include just the classes from the dependency com.googlecode.json-simple:json-simple.
<project>
...
<build>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<artifactSet>
<includes>
<include>com.googlecode.json-simple:json-simple</include>
</includes>
</artifactSet>
</configuration>
</execution>
</executions>
</plugin>
...
</plugins>
</build>
...
</project>

For this kind of purpose i would suggest to use the maven-shade-plugin which will create a ueber-jar which can be controlled in many ways.
With the shade plugin you can exclude things you don't like. But this might be caused by not using a separate maven module where you can control the dependencies.

Using maven Shade would work fine, one-jar would have done the job too.
But we finally decided that packaging jdom in our extension would be a bad practice.
So instead we gonna do this:
|-Root application Folder
|-Extension Folder
|-MyExtension.jar
|-libs Folder
|-jdom.jar
The jar into the lib folder will be loaded dynamically and won't be loaded if the extension cannot find the appropriate libs into the libs folder.
For the people who look to solve my primary problem please check out #khmarbaise Answer.

Related

Migrate Maven-plugins to Gradle: What happens with plugin configurations?

I want to migrate my build process from Maven to Gradle. I was wondering about what happens to the configuration-tag.
For example, i got this code block in the pom.xml
<plugin>
<!-- https://samaxes.github.io/minify-maven-plugin/index.html -->
<groupId>com.samaxes.maven</groupId>
<artifactId>minify-maven-plugin</artifactId>
<version>1.7.4</version>
<executions>
<execution>
<id>default-minify</id>
<configuration>
<jsSourceDir>static/js/app</jsSourceDir>
<jsSourceFiles>
<jsSourceFile>javascript.js</jsSourceFile>
<jsSourceFile>wiki-script.js</jsSourceFile>
<jsSourceFile>sidr/sidr.js</jsSourceFile>
</jsSourceFiles>
<webappTargetDir>${basedir}/src/main/webapp</webappTargetDir>
<jsEngine>CLOSURE</jsEngine>
</configuration>
<goals>
<goal>minify</goal>
</goals>
</execution>
</executions>
</plugin>
I know that Gradle doesn't have this plugin. But if i want Gradle to do something that produces the same result, i don't really know how. Do i need tasks for this?
You will need to either:
Find an equivalent Gradle plugin that offers similar capabilities as minify-maven-plugin
Create your own plugin: Developing Custom Gradle Plugins
From a quick Google search, it seems the org.padler.gradle.minify plugin offers the same capability the Maven one does.
https://plugins.gradle.org/plugin/org.padler.gradle.minify
https://github.com/616slayer616/gradle-minify-plugin
Thank you for your answer. I found that one too. But i have like half a dozen of other plugins with the configuration-tag, for example <configuration> ...... </configuration>. So actually my question was what options do i have with gradle to accomplish a similar effect, like how do i configure a plugin in Gradle. Not how to create my own plugin, but how to add some extras to an existing plugin.
EDIT:
Nevermind, i found more information regarding the configuration on the plugins github, But thank you nevertheless

Maven : exclude target/generated-sources from compilation

This question, just to be sure my interpretation is correct :
I'm using Mojohaus jaxb2-maven-plugin to generate java classes from .xsd files, and by default it puts them in target/generated-sources
Now, I want to get track of these classes in source control (target is of course excluded), and I may one day slightly customize one with an annotation or a line of code, and I may even change my class generation plugin, so what do is I copy these classes and packages in src/main/java
This upsets Maven when I try to compile because he considers "target/generated-sources" as a source directory and he finds all clases twice. For what I understand, I can exclude classes inside a source directory, but I can't remove a source directory from Maven build, am I right ?
So the only solution would be to configure my jaxb2 plugin to generate the classes elsewhere, right ?
UPDATE :
Ok, this doesn't work as I thought, if I change the outputDirectory of my jaxb plugin, it's still included as a source directory by Maven, and I have no clue why.
<configuration>
<outputDirectory>${project.build.directory}/tatata/jaxb</outputDirectory>
</configuration>
UPDATE 2 : The explanation is the plugin is adding the outputDirectory as a maven source directory during the generate-sources phase of the build, and it's not optionnal or customizable.
First things first, do not add generation code to source control. Do not modify it manually. You will get into trouble. Believe me, I've seen it too many times. A new version of the schema and you're lost.
Ok, now to your question.
With maven-jaxb2-plugin you could turn off adding generation directory as a compile source root with:
<configuration>
<addCompileSourceRoot>false</addCompileSourceRoot>
</configuration>
Disclaimer: I'm the author of maven-jaxb2-plugin.
The answer from Lexicore is an interesting lead but my question was about the plugin I'm currently using, not how to do it with an other plugin.
So here is the workaround for the Mojohaus plugin : you can just skip the generate-sources by default (no need to do this task at every build when your model changes once in a week, then once in a year), and trigger it only when needed using a dedicated maven profile : How to skip generate-sources in Maven
you can always specify the target directory(generateDirectory) in pom config file as below. Hope it helps
`
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.12.3</version>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<schemaLanguage>WSDL</schemaLanguage>
<generateDirectory>${basedir}/src/main/java</generateDirectory>
<generatePackage>com.myproj.proxy</generatePackage>
<schemas>
<schema>
<!-- <url>${project.basedir}/src/main/resources/wsdl/test.wsdl</url> -->
<fileset>
<!-- Defaults to schemaDirectory. -->
<directory>${basedir}/src/main/resources/wsdl</directory>
<!-- Defaults to schemaIncludes. -->
<includes>
<include>*.wsdl</include>
</includes>
</fileset>
</schema>
</schemas>
</configuration>
</plugin>
`

Always run proguard-maven-plugin before install phase

What I am trying to do, is to obfuscate a certain packages in a multi module application, before it gets installed to my local repository, so that the final package will be an EAR file which contains obfuscated jars.
I tried to obfuscate the jars during EAR building process without success. Now i want to build the EAR with obfuscated jars instead ob obfuscating then during the build.
So I've got the following plugin configuration:
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.0.11</version>
<dependencies>
<dependency>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard-base</artifactId>
<version>${version.proguard}</version>
</dependency>
</dependencies>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>proguard</goal>
</goals>
</execution>
</executions>
<configuration>
...
</configuration>
</plugin>
So there are two problems for me:
Progruard always runs after the install phase, so that the EAR build always gets the not obfuscated jars
I always have to add proguard:proguard to the maven command, which of course fails in a multi module project where some modules don't have to be obfuscated
So my questions:
How can I obfuscate the package before it gets installed?
How can I make plugins like this one run on default without adding <phase>:<goal> to the maven call?
Thnx.
It seems that for the proguard plugin to work, JAR files are needed. Perhaps you can achieve this by attaching the proguard plugin's proguard goal to the package phase (and not process-classes phase) of the default Maven build life cycle as proposed here by Alexey Shmalko. It's not clear to me if you are using the maven-shade-plugin, but if you are, then place the proguard plugin configuration your in pom.xml after that of maven-shade-plugin (this is because both these plugin attach to the same phase: package).
My expectation is that since package phase is achieved before install phase, it should give you the effect you are looking for.

How do I write a maven plugin which actually runs?

The instructions here seem very clear:
http://maven.apache.org/guides/plugin/guide-java-plugin-development.html
However, the first problem I run into is that the dependencies are wrong. I also needed to reference the maven-plugin-annotations dependency.
Then, when I attempt to run I get the "No plugin descriptor found at META-INF/maven/plugin.xml" error. I haven't figured out what to do about that.
I've found lots of pages referencing the maven-plugin-plugin, but I can't figure out how to add it to the pom so that it actually does anything which allows my own plugin to run.
Is there an updated version of the plugin development instructions which actually mentions the need to use maven-plugin-plugin?
If I can't get this to work I'm just going to go back to using exec-maven-plugin. It's uglier, but at least it works easily.
There are actually several terrific resources from Sonatype for learning how to write plugins:
Maven the Complete Reference: Writing Plugins
Maven Cookbook: Creating an Ant Maven Plugin
Maven Cookbook: Writing Plugins in Groovy
If I recall correctly, you need to configure the maven-plugin-plugin this way to avoid the "No plugin descriptor found..." issue.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-plugin-plugin</artifactId>
<version>3.2</version>
<configuration>
<!-- see http://jira.codehaus.org/browse/MNG-5346 -->
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
</configuration>
<executions>
<execution>
<id>mojo-descriptor</id>
<goals>
<goal>descriptor</goal>
</goals>
</execution>
</executions>
</plugin>
I forked a simple GitHub project called maven-wrapper (port of the Gradle wrapper) to make it a Maven plugin.
"It should be easy" for you to figure out pieces that you may eventually be missing:
Maven wrapper plugin(Mojo)
Maven Wrapper full POM

Providng maven build output as a plugin dependency

I have a custom factory implementation I'd like to provide to wro4j maven plugin through a string parameter. Trouble is the factory is built in the same project as the plugin so the plugin doesn't get passed the output from the build and i get a nice ClassNotFoundException.
I'm aware that there is an annotation I could attach to the wro4j mojo to make it aware of the build output but that would require patching and building wro4j from source which doesn't sound smart. I'm also not keen on creating a whole different artifact just to contain my 5 line factory implementation. It feels like there should be an easier way, so the question is
Is there a way to pass build artifacts to a plugin in the same pom WITHOUT editing the mojo?
Have to guess what the issue is without an actual plugin configuration. But generally, if you need to add dependency (or class) to some of your plugins, you will have to wrap that class into its own artifact, i.e. move it into a separate project.
Fundamentally Maven does plugin dependency resolution before kicking in the rest of build cycle, so your classes may haven't been compiled yet at that point.
Try instructing the wro4j plugin to execute in the process-classes phase instead of the compile phase, when your factory class is compiled (process-classes happens right after compile):
<plugin>
<groupId>ro.isdc.wro4j</groupId>
<artifactId>wro4j-maven-plugin</artifactId>
<version>${wro4j.version}</version>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<configuration>
<wroManagerFactory>...</wroManagerFactory>
</configuration>
</plugin>

Resources