I have many projects is my EAR , and we have configured maven for automated source generation for each projects using eclipse "external tools configurations" (org.eclipse.ui.externaltools.programLaunchConfigurationType).
But currently I have to go to "Run --> External Tools configuration" and run generate each sources manually one after another.
Is there any way I can automate this process, which will enable me to run these configurations one after another automatically ?
you can use multi module maven project and build project just by one click and then configure maven source generation as following
on parent pom use
<modelVersion>4.0.0</modelVersion>
<name> foo - root </name>
<groupId>com.foo</groupId>
<artifactId>bar</artifactId>
<version>3.0.9</version>
<packaging>pom</packaging>
on childeren
<parent>
<groupId>com.foo</groupId>
<artifactId>bar</artifactId>
<version>3.0.9</version>
</parent>
and finally for source generation
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>attach-sources</id>
<phase>prepare-package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
look at here and here
Related
I was looking for some tool to capture the Java compatibility differences between the artifacts generated in the current and previous build of our project. The tool should be part of our daily CI/CD build.
After some googling, I planned to use japicmp to compare between two SNAPSHOT versions, as I found it was fulfilling my requirements, as well as the project is being maintained well.
I tried with the following POM:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.rohan</groupId>
<artifactId>TestProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>${project.groupId}:${project.artifactId}</name>
<build>
<plugins>
<plugin>
<groupId>com.github.siom79.japicmp</groupId>
<artifactId>japicmp-maven-plugin</artifactId>
<version>0.11.1</version>
<configuration>
<oldVersion>
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<type>jar</type>
</dependency>
</oldVersion>
<newVersion>
<file>
<path>${project.build.directory}/${project.artifactId}-${project.version}.${project.packaging}</path>
</file>
</newVersion>
</configuration>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>cmp</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
However, during execution, the Maven dependency resolver is fetching the Older version of the artifact from the build target directory, and not from the Local repository, which is eventually causing the Older and Newer version to be the same. Our project only releases the artifacts as SNAPSHOT releases with same version number. Hence I am tied up there...
Can someone please advise me how to go about here? Thanks!
UPDATE
I went around this, by copying the older SNAPSHOT artifact in a different folder, during the initialize phase, and then used the same in japicmp during package phase. Following is my POM:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.rohan</groupId>
<artifactId>TestProject</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>${project.groupId}:${project.artifactId}</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<id>copy-old-version</id>
<phase>initialize</phase>
<goals>
<goal>copy</goal>
</goals>
</execution>
</executions>
<configuration>
<artifactItems>
<artifactItem>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<type>${project.packaging}</type>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/olderVersion</outputDirectory>
</configuration>
</plugin>
<plugin>
<groupId>com.github.siom79.japicmp</groupId>
<artifactId>japicmp-maven-plugin</artifactId>
<version>0.11.1</version>
<executions>
<execution>
<phase>verify</phase>
<goals>
<goal>cmp</goal>
</goals>
</execution>
</executions>
<configuration>
<oldVersion>
<file>
<path>${project.build.directory}/olderVersion/${project.artifactId}-${project.version}.${project.packaging}</path>
</file>
</oldVersion>
<newVersion>
<file>
<path>${project.build.directory}/${project.artifactId}-${project.version}.${project.packaging}</path>
</file>
</newVersion>
</configuration>
</plugin>
</plugins>
</build>
</project>
I will really appreciate if someone can advise me a better way, or a better tool which can resolve my purpose. Thanks!
Your point is that you are misusing the meaning of a SNAPSHOT in maven. A SNAPSHOT is a development artifact that is supposed to change frequently and overridden by each build cycle. maven will search for the specified artifact first in your local repository, where it will find your latest version and check for the first time a day the remote respository for a newer SNAPSHOT version. Hence, SNAPSHOTs have a special meaning in maven and shouldn't be used for releases. For more information see here or here.
The maven plugin of japicmp utilizes the maven framework to lookup the latest SNAPSHOT. Hence, it has no influence on the lookup procedure and it will work like all other maven plugins and take the latest SNAPSHOT either from your local repository or from the remote repository (if it is there newer than in your local one).
Please implement a release procedure that is conform to the maven proposal and do not use SNAPSHOTS as "releases" as your next build will override it again.
If for whatever reason you cannot release to your Nexus repository, you may think about installing your releases at least in your local repository according to the maven conventions. This page explains how to install a local jar file as maven artifact with a specific version.
I have an original java webapp (that thus produces a WAR file) which is Maven-managed, let's call it webapp.
I like to keep its Maven configuration as it is, but at times I need to, say, post-produce that generated WAR by manipulating its contents (or anyway apply generic operations on it).
So I made a multimodule project:
- multimodule
+-- webapp
+-- operator
The operator could do several things. For instance, it calls a (Java) command line program that does some checks on a WAR: how do I take the 'webapp' module output (i.e. the WAR file) and set it as input of the operator module?
I have no clue on how to do this nor on what to search on the net, so I'm stuck.
You need to make webapp a dependency of the operator project.
Sample POM of operator:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<version>0.0.1-SNAPSHOT</version>
<groupId>my-groupid</groupId>
<artifactId>operator</artifactId>
<dependencies>
<dependency>
<groupId>my-groupid</groupId>
<artifactId>webapp</artifactId>
<version>${project.version}</version>
<type>war</type>
</dependency>
</dependencies>
</project>
By creating an explicit dependency, Maven will build the webapp before the operator project in the reactor and you will be able to post-process that war.
Let's take an example by considering that you want to invoke a program taking this war as argument.
First, this new dependency has to be copied to a specific location. This is done with the maven-dependency-plugin. This plugin has a goal copy-dependencies which is used to copy all direct dependencies of a project to a location in the filesystem. Sample configuration would be:
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/libs</outputDirectory>
</configuration>
</execution>
</executions>
<plugin>
Now that the dependency is available in the filesystem, you can run a program using the exec-maven-plugin. Sample configuration, launching operator -param1 webapp.war:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.4.0</version>
<executions>
<execution>
<goals>
<goal>exec</goal>
</goals>
</execution>
<configuration>
<executable>operator</executable>
<workingDirectory>${project.build.directory}/libs</workingDirectory>
<arguments>
<argument>-param1</argument>
<argument>webapp.war</argument>
</arguments>
</configuration>
</executions>
</plugin>
Take a look at maven profiles.
You should be able to define two profiles and configure second profile to do your additional operations. If you follow this approach, you won't need two modules.
Maven is great. It mostly keeps me out of jar dependency hell by specifying versions of dependent packages in the pom configuration, and applies them automatically. It also has great integration with Eclipse via m2e, so that things work seamlessly in an IDE.
This is all great for dependencies that are globally known to Maven. However, sometimes, there are libraries that need to be included in a project that is not available in the Maven repos. In this case, I usually add them to a lib/ directory in my project. As long as they are in the classpath then things compile.
However, the problem is getting them to be included automatically when importing a project. I've been tolerating this problem with half-baked fixes and hacks for far too long. Every time someone installs this project, I have to tell them to manually add the jars in lib/ to their Eclipse build path so that all the errors go away. Something like the following:
I'm searching for a way to automate this process in a way that works with both the mvn command line program and Eclipse: more an emphasis on Eclipse, because it's nice to have projects that just compile when you import them.
I don't want to set up a repo server for this, nor do I have any in-house proprietary components that would warrant setting up anything locally. I just have some jar files where the developers don't use Maven; and I want to compile with them...I should just be able to include them in the distribution of my software, right?
I'm really looking for a reasonable way to implement this that will also work in Eclipse with no fuss. This is one solution I've found promising, but
there definitely doesn't seem to be an authoritative solution to this problem. The only other thing that comes close is the maven-addjars-plugin, which works okay but only on the commandline. This plugin is not bad, and has a pretty reasonable configuration:
<plugin>
<groupId>com.googlecode.addjars-maven-plugin</groupId>
<artifactId>addjars-maven-plugin</artifactId>
<version>1.0.5</version>
<executions>
<execution>
<goals>
<goal>add-jars</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>${project.basedir}/lib/java-aws-mturk</directory>
</resource>
<resource>
<directory>${project.basedir}/lib/not-in-maven</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
However, trying to get it to run in Eclipse involves adding the following mess about lifecycle mapping to your pom.xml, which I have never gotten to work; I don't even think it is configured to actually add anything to the Eclipse build path.
<pluginManagement>
<plugins>
<!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.-->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>
com.googlecode.addjars-maven-plugin
</groupId>
<artifactId>
addjars-maven-plugin
</artifactId>
<versionRange>
[1.0.5,)
</versionRange>
<goals>
<goal>add-jars</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
1) you can use system scope dependency
<dependency>
<groupId>test</groupId>
<artifactId>x</artifactId>
<version>1.0</version>
<scope>system</scope>
<systemPath>${basedir}/lib/x.jar</systemPath>
</dependency>
2) you can copy your x.jar to local maven repository as
repository/test/x/1.0/x-1.0.jar
and add a dependency as
<dependency>
<groupId>test</groupId>
<artifactId>x</artifactId>
<version>1.0</version>
</dependency>
You can use maven to install files from a project\lib folder to the local repo with the maven-install-plugin as below. I have done this before with JDBC drivers. You might have to create a separate pom for it and execute it with mvn -f installdeps.pom or something like that.
If you can get it to play nice and bind with a lifecycle like validate or something, then you can use the m2e plugin with Eclipse and it just might play nice and read dependencies straight from the pom.xml and install the jars as needed to the local repo.
<plugin>
<!-- We dont want children attempting to install these jars to the repo. -->
<inherited>false</inherited>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<executions>
<execution>
<id>Microsoft JDBC Driver File 1</id>
<phase>install</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<file>lib/sqljdbc4.jar</file>
<groupId>com.microsoft</groupId>
<artifactId>microsoft-jdbc-driver</artifactId>
<version>4.0</version>
<packaging>jar</packaging>
</configuration>
</execution>
<execution>
<id>ojdbc5</id>
<phase>install</phase>
<goals>
<goal>install-file</goal>
</goals>
<configuration>
<file>lib/ojdbc5.jar</file>
<groupId>com.oracle</groupId>
<artifactId>ojdbc5</artifactId>
<version>11.1.2</version>
<packaging>jar</packaging>
</configuration>
</execution>
</executions>
</plugin>
It seems to me that you could use the Maven Resources Plugin to do this for you. Just bind copying of resources to an appropriate lifecycle phase (a phase prior to compilation). You'll most likely need to tweak the maven-compiler-plugin so that these libraries are on the classpath when compiling and at runtime.
I have defined a maven multi modul build where one module is only used to generate sources. It will not compile, test or package and won't create any artifacts apart from the generate source files.
I haven't found a way yet to only execute the phases up to generate-sources on the generator module, regardless of the phase I specify when I start the multi module build. There are some solutions for skipping unwanted phases, but this is not a real option as there are just to many of them.
For those wondering, why I would want it: The build uses tycho and the fornax oaw plugin and so I had to split the build into two separate pom files and use a multi module build file to execute them "together".
After seeing your latest question I think I might have a solution for you.
I guess that all your ../projectN/generate/pom.xml has the top pom as its parent but I suggest that you create a special generate-parent pom with a special plugin management that will skip all the phases for you.
Create an extra folder called generate-parent at the top level:
<modules>
<module>../generate-parent/pom.xml</module> <!-- NEW FOLDER WITH POM -->
<module>../project1/generate/pom.xml</module>
<module>../project1/pom.xml</module>
<module>../project2/generate/pom.xml</module>
<module>../project2/pom.xml</module>
<!-- and many more projects with or without generate sub modules -->
</modules>
This new pom will inherit from the parent pom as usual but add only some extra plugin management:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>your-group</groupId>
<artifactId>your-parent-pom-artifact-id</artifactId>
<version>your-parent-version</version>
</parent>
<artifactId>generate-parent</artifactId>
<packaging>pom</packaging>
<name>${project.artifactId}-${project.version}</name>
<build>
<pluginManagement>
<plugins>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<id>default-resources</id>
<phase>none</phase>
</execution>
<execution>
<id>default-testResources</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<executions>
<execution>
<id>default-compile</id>
<phase>none</phase>
</execution>
<execution>
<id>default-testCompile</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.7.2</version>
<executions>
<execution>
<id>default-test</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>default-jar</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>default-install</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>default-deploy</id>
<phase>none</phase>
</execution>
</executions>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
Now with this pom all the default phases are disabled.
Now use this pom in all the generate projekcts. The above pom inherits all of the good stuff you have in your parent pom but just adds these special plugin management parts that disables the phases after the generate-sources.
project1/generate/pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>your-group</groupId>
<artifactId>generate-parent</artifactId>
<version>your-parent-version</version>
<relativePath>../../generate-parent</relativePath>
</parent>
...
The rest of your pom
...
</project>
This will effectively do what you want, the generate-parent is the middle-man that adds all the plugin management you want for just these generate projects.
So far as I understand, this is about using Xtext to create a code generator that is invoked in a maven build. I think you need to split up your project a bit more. You only need the generator to be built, when you change your grammar. So it would be a good idea to have a independent project (not a module) that contains the generator. You build and deploy your generator to a maven repository. In your normal build you use the fornax-oaw-m2 plugin to generate your sources in the generate-sources phase as you are doing now. You just need to include the generator as a dependency for the fornax-oaw-m2 plugin.
EDIT:
So to come back to your multi module project you want to build: I suggest that there is a module that only contains the resources from which you generate the sources and nothing else. The other java sourcec should be contained in their own module. Then I can suggest two alternatives for using the generator:
Run the generator in the module that contains the resources from which you generate the sources and set relative paths appropriately
Run the generator in the module that should contain the generated sources and include the module with the resources as a dependency (you may need to unpack that dependency before generating resources)
You still always generate in the generate-sources phase. In the 2nd alternative, the configuration of the fornax-oaw-m2 plugin will be duplicated, if you need generate sources to a set of different modules. But I think that this is more the maven way, as you only change the project you are currently building. In the first alternative, you would have to declare the dependencies from the modules, where source is generated into to the module that does the source generation. This seems a bit awkward.
My situation is:
I have a project that scan a directory of libs.
This project dosen't has dependence with other projects (jars), but this dynamically load them from the directory to his classloader (is a kind of plugin architecture).
Both projects are under a pom project
Examples of poms:
Parent:
<groupId>mygroup</groupId>
<artifactId>myparent</artifactId>
<packaging>pom</packaging>
<version>1.0</version>
...
"Plugin":
<parent>
<artifactId>myparent</artifactId>
<groupId>mygroup</groupId>
<version>1.0</version>
</parent>
<groupId>mygroup</groupId>
<artifactId>myplugin</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
...
"Loader":
<parent>
<artifactId>myparent</artifactId>
<groupId>mygroup</groupId>
<version>1.0</version>
</parent>
<groupId>mygroup</groupId>
<artifactId>myloader</artifactId>
<packaging>war</packaging>
<version>1.0</version>
...
Now, I need to generate the jar "plugin" and copy it to a defined directory in the project "loader" when I build it.
This have to work locally in eclipse and in jenkins automatically builds.
Someone has any idea how I can do this?
Basically it solved in four steps:
I configure the plugin "maven-assembly-plugin", in my "plugin" project, to copy the jar in a relative path within the project "loader".
In this configuration I specify the property "descriptorRef" in jar-with-dependencies, this helps me to pack the necessary libraries into the jar
I configure the plugin "maven-copy-plugin", in my "plugin" project, to copy the properties in the same relative path within the project "loader"
The pom.xml from my "plugin" project stay like this:
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<outputDirectory>${my.output.directory}</outputDirectory>
<archive>
<manifest>
<addClasspath>true</addClasspath>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
<plugin>
<groupId>com.goldin.plugins</groupId>
<artifactId>maven-copy-plugin</artifactId>
<version>0.2.3.6</version>
<executions>
<execution>
<id>create-archive</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<resources>
<!-- Copy config properties -->
<resource>
<targetPath>${my.output.directory}</targetPath>
<directory>${project.basedir}/conf</directory>
<includes>
<include>*.properties</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
On the other hand, I set the project to consume the plugins from the directory ${my.output.directory}
To automate the build in eclipse I create a new type of program builder for the project. This builder run the command "mvn assembly:assembly".
Step 1:
Step 2:
Step 3: In the tab "Build Options" you can configure details of this execution.
For jenkins, I create a dummy plugin which is used only from the tests.
Run maven install for plugin, which puts the resulting jar in your local maven repo. Then specify plugin in your dependencies section as a dependency. In this case, even though these projects are siblings, they are only siblings in the sense that the parent is specify the build order when mvn goals are run in parent. Their actual build artifacts must be included by the sibling if you intend to use it there.