How to stop Apache maven <outputDirectory> to overwrite the folder - maven-2

I have the following directory hierarchy:
generated
|
| -->java
Java directory has the following package: com.model
that contains java models that I copy/paste from somewhere before I compile the application.
The issue that I use Protocol buffer and I tell maven to output the generated files on same previous directory BUT over a new package:
Result : Protocol buffer generates the new package and deletes the old package.
I have no idea why does it do that although the package names are different?
Here is that part of pom I use to generate java from protocol buffer:
<plugin>
<groupId>com.google.protobuf.tools</groupId>
<artifactId>maven-protoc-plugin</artifactId>
<configuration>
<protocExecutable>C:\protoc.exe</protocExecutable>
<protoSourceRoot>./src/proto</protoSourceRoot>
<outputDirectory>./src/generated/java</outputDirectory>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>

if you look at the code for the plugin you'll see that the code has been hardcoded to clean the directory:
https://github.com/dtrott/maven-protoc-plugin/blob/master/src/main/java/com/google/protobuf/maven/AbstractProtocMojo.java#L154
// Quick fix to fix issues with two mvn installs in a row (ie no clean)
cleanDirectory(outputDirectory);
There's 2 ways to solve this..either set the output directory to a temp directory and then use the maven copy plugin or the maven build plugin to copy the files into the directory of your choice, or modify the maven plugin to remove that line (or better yet make it configurable).
Tommy

I have solved my issue by the following :
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>generate-resources</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<tasks>
<delete dir="./destination"/>
<copy todir="./destination">
<fileset dir="./source"/>
</copy>
<delete dir="./source"/>
</tasks>
</configuration>
</execution>
</executions>
</plugin>
However , I get this error "An Ant BuildException has occured: Only one of tofile and todir may be set"

Related

Maven - Replace a file in a Jar

I want to replace a file in an existing jar/zip file while doing a Maven build. What is the easiest way to achieve this?
My favorite for this sort of tasks is maven-antrun-plugin which brings you complete ant functionality.
You can use it like this:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<executions>
<execution>
<id>repack</id>
<phase>compile</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<!-- note that here we reference previously declared dependency -->
<unzip src="${org.apache:common-util:jar}" dest="${project.build.directory}/tmp"/>
<!-- now do what you need to any of unpacked files under target/tmp/ -->
<zip basedir="${project.build.directory}/tmp" destfile="${project.build.directory}/common-util-modified.jar"/>
<!-- now the modified jar is available -->
</target>
</configuration>
</execution>
</executions>
</plugin>
But remember - never modify any files in your local repository - in this example pointed to by ${org.apache:common-util:jar}. Doing so would affect your further builds of all your projects on the same computer (= against the same local repo).
Such builds are also irreproducible (or hard to reproduce) on other machines.
I don't think there is a dedicated plugin to do this but I would imagine you can use the exec plugin and information from Updating .class file in jar to accomplish this.

Maven war artifact with car extension

I am trying to use Maven to generate an artifact for deploying on Vignette Portal. The packaging is exactly the same as a war artifact but the file should have car extension instead.
Options I've tried and I've not been able to complete.
Use war plugin and rename the final artifact (keeps adding .war extension)
Use assembly plugin with zip descriptor (not able to change .zip to .car extension)
Create a new packaging type as described here (can't use war plugin for .car extension)
Which would be the easiest 'Maven' way to generate the .car file? Could you give me some guidance?
Thank you.
I think it's not possible to rename the main deliverable artifact of a project.
Anyway, in the past, what I've done so far was making maven copy the file with a new name and then "attach" it to the deliverables of a build; by configuring two plugins:
maven-ant-run to copy
maven-build-helper to attach in order to be deployed to my repo along with the main artifact of my project.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<configuration>
<target>
<copy file="${project.build.directory}/${project.build.finalName}.war"
tofile="${project.build.directory}/${project.build.finalName}.car" />
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
And the second:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>attach-instrumented-jar</id>
<phase>verify</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>${project.build.directory}/${project.build.finalName}.car</file>
<type>car</type>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
I hope that can help you. At least until you find a better solution.

Disable the default-jar execution

I am using Maven Assembly plugin to pack a jar file.
But when I run mvn package, maven always trigger the [jar:jar {execution: default-jar}] to create a default jar file.
So I will have 2 jar files (one created by Assembly plugin and one created by Maven jar which i don't want to be created).
How can I turn off the default-jar execution?
In my pom.xml, I am using: <packaging>jar</packaging>.
I don't want to change it to <packaging>pom</packaging>.
(...) So i will have 2 jar files (one created by assembly plugin and one created by maven jar which i dont want to be created).
Looks like you're doing pretty complicated things. Maybe Maven is not the right tool in your case.
How can I turn off the execution: default-jar.
You can set the <phase> of the corresponding execution to something unknown, like none:
<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-assembly-plugin</artifactId>
<version>2.2</version>
<configuration>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<!-- this is used for inheritance merges -->
<phase>package</phase>
<!-- append to the packaging phase. -->
<goals>
<goal>single</goal>
<!-- goals == mojos -->
</goals>
</execution>
</executions>
</plugin>
This seems to work as long as you're providing something else to be installed, like an assembly (I only tested install). But of course, this is a hack.
While not a direct answer to the question, you could exclude the jar created by maven jar using <useProjectArtifact>false</useProjectArtifact>

Maven2: How do I generate a file that contains the names of the project's dependencies?

I would like to place the names of the dependencies in a text file that is distributed inside a package that is built with Maven.
I am planning to use the maven assembly plugin to generate the tarball package, and use filtering to put the names in the text file.
The only problem is, I don't know how to reference the dependencies in the first place.
You don't need to use filtering for that, use the Maven Dependency plugin and its a dependency:tree goal to display the dependency tree for this project. Set an output file with the... outputFile optional parameter. So the configuration might look like:
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>tree</id>
<phase>prepare-package</phase>
<goals>
<goal>tree</goal>
</goals>
<configuration>
<outputFile>${project.build.outputDirectory}/dep.txt</outputFile>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
...
</project>
Running the package phase would generate the dependency tree in target/classes/dep.txt and package it in the artifact. Adapt it to suit your needs.
You can use the maven-dependency-plugin dependency:tree to output the tree of dependencies into a file.
mvn dependency:resolve seems to be what you are looking for. Put following plugin configuration to your POM file:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>list-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>resolve</goal>
</goals>
<configuration>
<outputFile>dependencies.txt</outputFile>
</configuration>
</execution>
</executions>
</plugin>
It will produce file dependencies.txt with content similar to:
The following files have been resolved:
am:amagent:jar:1.0:system
am:amclientsdk:jar:1.0:system
aopalliance:aopalliance:jar:1.0:compile
asm:asm:jar:2.2.3:compile
com.sun.jdmk:jmxtools:jar:1.2.1:compile
com.sun.jmx:jmxri:jar:1.2.1:compile
com.sun.xml.bind:jaxb-impl:jar:2.1.12:compile
com.sun.xml.fastinfoset:FastInfoset:jar:1.2.2:compile
com.sun.xml.messaging.saaj:saaj-impl:jar:1.3.2:compile
commons-lang:commons-lang:jar:2.3:compile
commons-logging:commons-logging:jar:1.1:compile
dom4j:dom4j:jar:1.6.1:compile
javax.activation:activation:jar:1.1:provided
javax.jms:jms:jar:1.1:compile
javax.mail:mail:jar:1.4:compile
javax.xml.bind:jaxb-api:jar:2.1:compile
javax.xml.soap:saaj-api:jar:1.3:compile
junit:junit:jar:4.4:test
log4j:log4j:jar:1.2.15:compile

Is it possible to single out and run a specific goal bound to a maven phase?

Updated to (hopefully) clarify: If a goal is defined to run during a given phase, is it possible to run the individual goal without running thru all phases. In other words would it be possible to run the antrun:run goal (which is defined as part of the install phase below) without getting dependencies, generate-resources, compiling, testing, package, etc?
I'm using the antrun plugin to create a zip file during the package phase and to delete and copy some files during the install phase. I understand how to run single maven plugin goals, for example: mvn antrun:run. However, is there a way to run a specific execution's goal? Something like mvn antrun:run:execution-id, or mvn phase:antrun:run?
Basically, I'd be nice if I can tell maven to do nothing else but run the ant tasks defined below inside the deploy phase, for example. It's kind of tedious having to wait for maven to go thru all the phases just to check if the ant tasks in the deploy phase are working correctly.
<executions>
<!-- create zip file -->
<execution>
<id>create-zip</id>
<phase>package</phase>
<configuration>
<tasks>
...create zip...
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
<!-- do some other stuff -->
<execution>
<id>copy-files</id>
<phase>install</phase>
<configuration>
<tasks>
...delete some files, copy some files ...
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
In other words would it be possible to run the antrun:run goal (which is defined as part of the install phase below) without getting dependencies, generate-resources, compiling, testing, package, etc?
No it's not. While you can configure a plugin (with a <configuration> section under the <plugin> element) and call in on the command line, you can't invoke a specific executionid (and consequently the <configuration> specific to an <execution>).
The only solution in your case would be to declare the antrun plugin in a profile, let's say my-profile, to duplicate the following part of the configuration to configure the plugin in this profile:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.3</version>
<configuration>
<tasks>
... delete some files, copy some files ...
</tasks>
</configuration>
</plugin>
and to call with the right active profile:
mvn antrun:run -Pmy-profile
Try the exec maven plugin...
For ex:
When you run jboss with maven, you can't see the jboss console output, but I need it to display, so what I did is I wrote a java file that reads in server.log(the server console output) as it changes to display the changes so it appears that jboss console is actually showing(a bit hack-ish but working). So I come to the point of answering your question, during the pre-integration-test I executed a java goal which starts my java program. Here is how , using execute plugin of course :
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>console-start</id>
<phase>pre-integration-test</phase>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>org.eclipse.console.Main</mainClass>
</configuration>
</plugin>
You just run the install and it executes during the pre-integration-test, however if you just want to execute something like java, use the execute plugin. Sorry if the answer not appropriate, I didn't have the patience to read your question in details, my work hours are over .. cheers