I would like to overlay another person's project, using customizations of specific files (ie one file would use a different controller, or display something in one way, or have different processes). We have been using an overlay that takes all of the files I have in my repository, and overlaying all of the files on top of their files so that my smaller set of customizations still act like the larger project should. We have accomplished it like this so far, but it plays havoc on the IDE. Is there a better way? I tried using maven-builder-helper-plugin but it gave me duplicate classes on the java files I had overriden.
<build>
<sourceDirectory>target/overlay</sourceDirectory>
<resources>
<resource>
<directory>target/overlay</directory>
<filtering>false</filtering>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
<plugins>
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<configuration>
<tasks>
<copy todir="target/overlay" overwrite="true">
<fileset dir="src/main/java">
</fileset>
<fileset dir="src/main/resources">
</fileset>
</copy>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>initialize</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.sample.service</groupId>
<artifactId>sampleService</artifactId>
<classifier>sources</classifier>
<type>jar</type>
<overWrite>true</overWrite>
<outputDirectory>target/overlay</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
I should note that I'm absolutely fine with using a different direction than this one. I just couldn't figure out a better way to include all of the resource & source files that are needed from them to keep the project running properly. This is for a module that is a part of a web app. The module that is being built and the module it is overlaying are both jar's
We do this using the maven war overlay feature (read about it here). To do this we simply have a dependency from our web client module onto a war type <type>war</type>, and override what we need to in our module. Maven will take the contents of the dependent war and use its files to provide content for our web client, but if there is a clash on filename it'll take the file from our web client, not from the dependent jar. It's as if it takes the dependent jar and overlays our client on top of it to produce a new war. We do this very simply, without any need for ant run -- in years of using maven I have never had to resort to antrun (I consider it an antipattern).
You mention in the comments that you have a separate problem dealing with some xml files. This can be handled by the resource plugin, if you tell it which directory your files are in, and give it a wildcard to define the files you need copying.
So, I figured out a solution that allows me overlay the artifact without messing around with the source directory. Instead of slapping all of the files I want to overlay on top of the artifact files, I realized a simpler way would be to expand the artifact, remove the duplicate classes/resources, and use it as an additional source. I created my own plugin that takes as many 'source' directories as I want and it filters them in the order loaded.
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>initialize</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.sample.service</groupId>
<artifactId>sampleService</artifactId>
<classifier>sources</classifier>
<type>jar</type>
<overWrite>true</overWrite>
<outputDirectory>${additional-source-folder}</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>mn-stateadvantage</groupId>
<artifactId>duplicateSourceRemover-maven-plugin</artifactId>
<version>1.0-SNAPSHOT</version>
<executions>
<execution>
<goals>
<goal>removeDuplicates</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<sourceDirectories>
<param>src/main</param>
<param>${additional-source-folder}</param>
</sourceDirectories>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-resources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${additional-source-folder}</source>
</sources>
</configuration>
</execution>
<execution>
<id>add-resource</id>
<phase>generate-resources</phase>
<goals>
<goal>add-resource</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>${additional-source-folder}</directory>
<excludes>
<exclude>**/*.java</exclude>
</excludes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Related
I've been trying to read java files that are stored inside target/generated-sources folder. To store these files I have used below plugin in pom.xml file
<!-- For Code Generation -->
<plugin>
<groupId>org.jvnet.jaxb2.maven2</groupId>
<artifactId>maven-jaxb2-plugin</artifactId>
<version>0.12.3</version>
<executions>
<execution>
<id>add-source-for-demoapp</id>
<goals>
<goal>generate</goal>
</goals>
<configuration>
<schemaDirectory>src/main/resources/xsd</schemaDirectory>
<schemaIncludes>
<include>myschema.xsd</include>
</schemaIncludes>
<generateDirectory>target/generated-sources/xjc/workflow</generateDirectory>
<generatePackage>com.websystique.xml.workflow</generatePackage>
<!-- For including equals,hashcode and toString methods in generated code -->
<plugins>
<plugin>
<groupId>org.jvnet.jaxb2_commons</groupId>
<artifactId>jaxb2-basics</artifactId>
<version>0.9.4</version>
</plugin>
</plugins>
<args>
<arg>-Xequals</arg>
<arg>-XhashCode</arg>
<arg>-XtoString</arg>
</args>
</configuration>
</execution>
</executions>
</plugin>
Now this plugin generated few java files and to access those file I have used below plguin inside pom.xml
<!-- For Adding Generated code directory as source folder -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.9</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${basedir}/target/generated-sources/xjc/workflow/com.websystique.xml.workflow</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
I have tried several ways to read these files from target folder as shown below. But nothing is working.
Apart from above 2 plugins I'm also using spring-boot-maven-plugin sonar-maven-plugin maven-surefire-plugin
https://www.benchresources.net/jaxb-a-xml-parsing-technique/
Once files are generated then add generated/java/source folder under classpath in eclipse.
I am looking to delete a folder (api-docs) from the target folder. When I do maven build, when the target folder is generated, it should exclude that folder(api-docs). Target contains Classes, codegen, generated-sources, javadoc-bundle-options, maven-archiver, maven-status, test-classes and a war file. I need to exclude(api-docs) which is present in codegen Codegen > generated-sources> web> api-docs( contains css, fonts, images, lang, lib, specs and some other js and html files)
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>build</phase>
<goals>
<goal>build</goal>
</goals>
<configuration>
<tasks>
<delete>
<fileset> dir="${project.build.outputDirectory}/target/codegen/generated-sources/web/api-docs"/>
</delete>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
`
I added that in pom.xml, but couldn't able to delete. Please suggest
Here is the entire contents of build from pom file
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>com.xxx.chassis.api.plugins</groupId>
<artifactId>codegen-maven-plugin</artifactId>
<version>${codegen.plugin.version}</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>generate</goal>
</goals>
</execution>
</executions>
<configuration>
<templateDir>chassis-archetypes</templateDir>
<configFile>${project.parent.basedir}/codegen-config.yaml</configFile>
<specifications>
<specification>${project.parent.basedir}/partnerships-originations-product-offer-id.yaml</specification>
</specifications>
<basePackage>com.xxx.papi.popoi</basePackage>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.8</version>
<executions>
<execution>
<phase>build</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<delete>
<fileset dir="${project.build.directory}/codegen/generated-sources/web/api-docs/swagger-ui.min.js"/>
</delete>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${codegen.generated-sources}/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-javadoc-plugin</artifactId>
<configuration>
<sourcepath>${codegen.generated-sources}/java</sourcepath>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
Please share the entire contents of the build->plugins section of your pom file. It should not be necessary to add the maven-antrun-plugin to your pom. The apidocs folder in your target directory is usually produced by the maven-javadoc-plugin which you possibly have present in your pom file. The first way to prevent the creation of the apidocs folder would be to remove that plugin declaration from your pom. An alternative way would be to supply the maven.javadoc.skip argument as per this answer: https://stackoverflow.com/a/9360317/7810853
The goal for the antrun-plugin is run, not build. Changing the pom.xml accordingly should help:
[...]
<goals>
<goal>run</goal>
</goals>
[...]
You also should double check in which phase the api-doc folder is created and you should call the ant-plugin in a later phase, for example package:
[...]
<phase>package</phase>
[...]
As a third point, the Maven variable ${project.build.outputDirectory} usually references the folder target/classes. Please check this answer for more details. Therfore, you could either use
<fileset dir="${project.basedir}/target/codegen/generated-sources/web/api-docs"/>
or - more precise -
<fileset dir="${project.build.directory}/codegen/generated-sources/web/api-docs"/>
I am trying to use the resources plug-in with the aim of copying the jar in the target directory to another directory (e.g. /target/runtime) once it has been built.
I can see resources are copied at the start of process, before the jar is built, so reading up on it seems I need to run this at validate phase, i.e. after the jar has been built. However this is not working. Other files are copied, but not the jar.
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.1</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/runtime</outputDirectory>
<resources>
<resource>
<filtering>true</filtering>
<directory>${project.basedir}/target</directory>
<targetPath>${project.build.directory}/target/runtime</targetPath>
<includes>
<include>*.jar</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
`<project>
[...]
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>copy</id>
<phase>package</phase>
<goals>
<goal>copy</goal>
</goals>
</execution>
</executions>
<configuration>
<artifactItems>
<artifactItem>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<type>jar</type>
<overWrite>false</overWrite>
<outputDirectory>${project.build.directory}/alternateLocation</outputDirectory>
<destFileName>optional-new-name.jar</destFileName>
</artifactItem>
</artifactItems>
<outputDirectory>${project.build.directory}/wars</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
</configuration>
</plugin>
</plugins>
</build>
[...]
</project>`
Please refer to this I have used this multiple times , seems to do the job.
The phase in your plugin definition for resource copying is defined as validate. The Jar is not built when this plugin runs. More information about lifecycle is defined here.
If you change the plugin phase as verify then it copies the file successfully as shown below,
I have a multi-module project where I build every project with tycho. Everything including the phase "install" works perfectly. Every module results in one artefact which are installed to my local maven repository...about 10 artefacts.
Now, I would like to make maven additionally copy all 10 artefacts to a local directory if the build successes. At the end, when I rebuilt my application, I should only see one directory with all (updated) artefacts.
Btw, how do the big companies get their product out of the maven repository?
You may define an aggregator module in your project, that has dependencies on all other projects and then use the maven-dependency-plugin to collect all jars
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-libs</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<includeScope>runtime</includeScope>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>true</overWriteSnapshots>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
Of course you can collect resource files like startup scripts etc using the same plugin. Create another execution
<execution>
<id>copy-sh-files</id>
<phase>package</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/scripts</outputDirectory>
<includes>bin/*.sh</includes>
</configuration>
</execution>
To put that all together into a single zip, you have to create an assembly file in src/assembly/zip.xml with that content
<assembly>
<id>zip</id>
<formats>
<format>zip</format>
</formats>
<fileSets>
<fileSet>
<directory>src/bin</directory>
<outputDirectory>.</outputDirectory>
<includes>
<include>*.cmd</include>
</includes>
<lineEnding>dos</lineEnding>
</fileSet>
<fileSet>
<directory>target/lib</directory>
<outputDirectory>lib</outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
</fileSets>
</assembly>
and add the maven-assembly-plugin to your build plugins
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptor>src/assembly/zip.xml</descriptor>
<finalName>yourProjectFinalName</finalName>
</configuration>
<executions>
<execution>
<id>zip-bundle</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
All these configuration are just one way to do it, but it is a good start. Big companies usually have various requirements for their packaging, including installers etc, so there is no one-size-fits-all solution and it's usually quite a process to get to the final solution.
Is there a way that I can get maven to only include specific .class files when importing dependencies into uber jar (shade). I'm looking for a way to get files that contain "Client" in their name to be pulled out of the dependency jars and added to the final jar. Any help would be wonderful.
You should be able to use the maven-dependency-plugin like this:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.10</version>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId><!--dependency groupId--></groupId>
<artifactId><!--dependency artifactId--></artifactId>
<version><!--depedency version--></version>
<includes>**/*Client*.java</includes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
If you are using the Maven Shade Plugin, you can a filter, which will allow you to filter which artifacts get shaded, but as well as which classes to exclude or include.
Here's the example they provide:
<filters>
<filter>
<artifact>junit:junit</artifact>
<includes>
<include>org/junit/**</include>
</includes>
<excludes>
<exclude>org/junit/experimental/**</exclude>
</excludes>
</filter>
</filters>