What's the best way to setup the eclipse project compiler configuration for Java 6 annotation processors?
My solution is to setup the org.eclipse.jdt.apt.core.prefs and factorypath files manually. This is a bit cumbersome:
Reference the processor jar in the factorypath file
Configure the eclipse annotation processor output directory (org.eclipse.jdt.apt.genSrcDir property in org.eclipse.jdt.apt.core.prefs)
Add the eclipse annotation processor output directory as source folder
One problem is that eclipse generated sources will be compiled with maven. Only maven clean compile is reliable as it removes the eclipse generated source files. (Eclipse and javac generated source files could be out of sync.)
Is there are better solution to configure maven without eclipse generated source files at the maven source path?
<project>
<properties>
<eclipse.generated.src>${project.build.directory}/eclipse</eclipse.generated.src>
</properties>
<build>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.4</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals> <goal>add-source</goal> </goals>
<configuration>
<sources>
<source>${eclipse.generated.src}</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<configuration>
<additionalConfig>
<file> <name>.factorypath</name>
<content><![CDATA[<factorypath>
<factorypathentry kind="VARJAR" id="M2_REPO/processor/processor.jar" enabled="true" runInBatchMode="false"/>
</factorypath>
]]> </content>
</file>
<file>
<name>.settings/org.eclipse.jdt.apt.core.prefs</name>
<content><![CDATA[
eclipse.preferences.version=1
org.eclipse.jdt.apt.aptEnabled=true
org.eclipse.jdt.apt.genSrcDir=${eclipse.generated.src}
org.eclipse.jdt.apt.reconcileEnabled=true
]]> </content>
</file>
</additionalConfig>
</configuration>
</plugin>
</plugins>
</build>
</project>
Update: You could try using the apt-maven-plugin. It currently provides three goals:
apt-process Executes apt on project sources.
apt:test-process Executes apt on project test sources.
apt:eclipse Generates Eclipse files for apt integration.
You can configure the goals to run as part of your build as follows:
<build>
...
<plugins>
...
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.0-alpha-2</version>
<executions>
<execution>
<goals>
<goal>process</goal>
<goal>test-process</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
...
</build>
By default the output directory is set to ${project.build.directory}/generated-sources/apt,
There is an open Jira against the compiler plugin to add APT support for Java 6, you can go and vote for it if this is something you want to to see in future versions.
I am using http://code.google.com/p/maven-annotation-plugin/ wich is simpler to configure. You can use it in two ways:
generate sources during compilation (configuration below)
generate sources "by hand" to src/main/generated and keep them on SCM
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<executions>
<execution>
<id>process</id>
<goals>
<goal>process</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<compilerArguments>-encoding ${project.build.sourceEncoding}</compilerArguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.bsc.maven</groupId>
<artifactId>maven-processor-plugin</artifactId>
<executions>
<execution>
<id>process-test</id>
<goals>
<goal>process-test</goal>
</goals>
<phase>generate-test-sources</phase>
<configuration>
<compilerArguments>-encoding ${project.build.sourceEncoding}</compilerArguments>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>${project.build.sourceEncoding}</encoding>
<!-- Disable annotation processors during normal compilation -->
<compilerArgument>-proc:none</compilerArgument>
</configuration>
</plugin>
There is a simpler solution in Eclipse Juno (I'm not sure about previous versions). In Preferences / Maven / Annotation Processing there are three modes for annotation processing. It is disabled by default, but I've tested both other options and worked like a charm for me. This way, you don't need to configure APT processing for every project or modify its pom.xml.
Related
I have a pom file that correctly generates the grpc and protobuf source files I need in target/generated-sources when run from the command line. But when I build in vscode those directories are empty and references to the protobufs are undefined. Here's the section of my pom file that builds the grpc source.
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.0</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.2.0:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:${grpc.version}:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
I added the following based on what I read in other posts to prevent vscode/eclipse from removing the generated source directories
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
</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>target/generated-sources/protobuf/grpc-java</source>
<source>/target/generated-sources/protobuf/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
When vs-code builds, the target generated-source directories are there, but there is no source in them. We had a similar problem with intellij but were able to work around it by running the maven command line build before opening intellij but that does not seem to work for vscode.
Use protoc-jar-maven-plugin instead.
Sample usage please view protoc-jar-maven-plugin.
I'm using Apache avro to generate some pojos, all work very well in run, expect that the generated source is marked as inexistent in imports on IDE (intellij) .
I tried to use build-helper-maven-plugin to add source, but it doesn't work
this is my maven configuration for apache avro and build helper plugins :
<plugin>
<groupId>org.apache.avro</groupId>
<artifactId>avro-maven-plugin</artifactId>
<version>${avro.version}</version>
<configuration>
<stringType>String</stringType>
</configuration>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>schema</goal>
</goals>
<configuration>
<sourceDirectory>${project.basedir}/src/main/avro/</sourceDirectory>
<outputDirectory>${project.build.directory}/generated-sources/</outputDirectory>
<imports>
<import>${project.basedir}/src/main/avro/errorkind.avsc</import>
</imports>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
Try changing your pom with following and run clean install and then you should be able to import.
<configuration>
<sourceDirectory>${project.basedir}/src/main/resources/</sourceDirectory>
<source>${project.build.directory}/generated-sources</source>
</configuration>
In POM InteliJ may give you a fake error after adding this but your build will success.
"generated-sources" reside under ${project.build.directory}/target folder
Also, try marking "generated-sources" as source directory. You can do that by:
Project Structure → Modules → Click the generated-sources folder and make it a sources folder.
I have a maven project with one war and several ear projects. Each ear project requires a slightly different war/WEB-INF/web.xml. Each ear's pom.xml uses com.google.code.maven-replacer-plugin:replacer and org.codehaus.mojo:truezip-maven-plugin to replace tokens in the web.xml, and then place that new web.xml in the final <project>-app.ear/web.war/WEB-INF. This all works great with building and creating the final EAR artifacts.
The problem I'm having is that when I run (using Netbeans, but that shouldn't matter), the web.xml used for deployment (<project>/target/gfdeploy/first-app/web_war/WEB-INF/web.xml) is the tokenized version. I tried adding execution phases for deploy, but that doesn't work.
How can I ensure that the run deploy has the modified web.xml so I can test my app during development?
Here is the relevant parts of the ear pom.xml:
<plugin>
<groupId>com.google.code.maven-replacer-plugin</groupId>
<artifactId>replacer</artifactId>
<version>1.5.3</version>
<executions>
<execution>
<id>package-replace</id>
<phase>package</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
<execution>
<id>deploy-replace</id>
<phase>deploy</phase>
<goals>
<goal>replace</goal>
</goals>
</execution>
</executions>
<configuration>
<file>${project.parent.basedir}/${web.xml}</file>
<outputFile>${project.build.directory}/${web.xml}</outputFile>
<replacements>
<replacement>
<token>#REALM_NAME#</token>
<value>${web.realm}</value>
</replacement>
</replacements>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>truezip-maven-plugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<id>package-replace-web-xml</id>
<goals>
<goal>copy</goal>
</goals>
<phase>package</phase>
<configuration>
<files>
<file>
<source>${project.build.directory}/${web.xml}</source>
<outputDirectory>${project.build.directory}/${project.build.finalName}/${web.zip}/WEB-INF</outputDirectory>
</file>
</files>
</configuration>
</execution>
<execution>
<id>package-replace-web</id>
<goals>
<goal>copy</goal>
</goals>
<phase>package</phase>
<configuration>
<files>
<file>
<source>${project.build.directory}/${project.build.finalName}/${web.zip}</source>
<outputDirectory>${project.build.directory}/${project.build.finalName}.ear</outputDirectory>
</file>
</files>
</configuration>
</execution>
<execution>
<id>deploy-replace-web-xml</id>
<goals>
<goal>copy</goal>
</goals>
<phase>deploy</phase>
<configuration>
<files>
<file>
<source>${project.build.directory}/${web.xml}</source>
<outputDirectory>${project.build.directory}/gfdeploy/${project.artifactId}/web-${project.version}_war/WEB-INF</outputDirectory>
</file>
</files>
</configuration>
</execution>
</executions>
</plugin>
I suggest you to keep your default src/main/webapp/WEB-INF/web.xml fully functional for running during development. Then, keep a similar file called src/main/webapp/WEB-INF/web-ear.xml with all the replacement preparation.
Wrap all your replacement plugin strategy inside a maven profile and targeted to the web-ear.xml file. Add to this profile a maven-war-plugin configuration that will use the alternative web-ear.xml file during build, instead of the default web.xml (check: http://maven.apache.org/plugins/maven-war-plugin/):
<profiles>
<profile>
<id>change-war-profile</id>
<build>
<plugins>
<!-- all your replacement plugins here -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webXml>src/main/webapp/WEB-INF/web-ear.xml</webXml>
</configuration>
</plugin>
<plugins>
</build>
</profile>
</profiles>
Make sure to activate this profile during the EAR maven build:
mvn package -Pchange-war-profile
you can run your war with the jetty-maven-plugin choosing the run-war goal.
That goal run the packaged war.
See: https://www.eclipse.org/jetty/documentation/9.4.x/jetty-maven-plugin.html#running-assembled-webapp-as-war
First of all, deploy phase (of the build lifecycle) means deployment a production ready artifact to the remote Maven repository (e.g., Nexus or Artifactory). Roughly speaking, artifact deploy can be treated as copying the artifact. Read the Introduction to the Build Lifecycle for more details.
Secondly, Apache Maven does not support application deploy to the application server out-of-the-box. However, there are several ways to do it, depending on the application server you use. Which one do you use?
Special plugin can be found for JBoss Application Server - jboss-as-maven-plugin. See usage example:
<project>
...
<build>
...
<plugins>
...
<plugin>
<groupId>org.jboss.as.plugins</groupId>
<artifactId>jboss-as-maven-plugin</artifactId>
<version>7.9.Final</version>
<executions>
<execution>
<phase>install</phase>
<goals>
<goal>deploy</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
...
</build>
...
</project>
Similar plugin can be found for GlassFish Server: glassfish-maven-plugin.
Also, if this is acceptable for you, you can perform 2-steps deploy from Netbeans:
Build the project: run mvn package with all your plugins are configured at package phase.
Deploy the project: run application on the app server from Netbeans if it is supported (See NetBeans Java EE Servers Support page).
Hope this helps.
My project can generate some additional help files automatically from the source code.
How do I have maven install these files into the generated JavaDoc package?
I couldn't fingure out how to have Maven:
run some class to generate the additional documentation, e.g. compile and launch src/main/java/mypackage/ListOptions.java aka mypackage.ListOptions to produce a list of all available options/modules/examples/etc. .
install the output files (I only could get Maven to install files from src/main/javadoc/resources into the site/apidocs/resources subfolder; but I want this documentation to live in the top level site/apidocs folder; more precisely I don't care about the site part at all, but about having a complete documetation in mypackage-0.1.0-SNAPSHOT-javadoc.jar; including non-Javadoc-generated auxillary information linked from javadoc).
Minimal example - Plugin configuration for maven:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<docfilessubdirs>true</docfilessubdirs>
</configuration>
</plugin>
Directory layout:
./pom.xml
./src/main/java/foobar/GenerateNonstatic.java
./src/main/javadoc/staticfile.js
./src/main/javadoc/resources/insubfolder.png
mvn package produces: javadoc in ./target/apidocs and ./target/foobar-0.0.1-SNAPSHOT-javadoc.jar. The file target/apidocs/resources/insubfolder.png ends up in folder target/apidocs/resources (and the .jar), but the staticfile.js is not installed.
How to run GenerateNonstatic.java to have the output included in the javadoc .jar is unclear to me. I don't see a hook to have exec:exec it run after javadoc, and before ./target/foobar-0.0.1-SNAPSHOT-javadoc.jar is built...
Long story, short answer. Both the javadoc:javadoc and javadoc:jar mojos have their drawbacks. The first is meant to build the javadoc for reporting; the latter will build the javadoc (into a different directory) and produce a jar package.
Some of the suggested answers did not work well because of this - they would execute javadoc twice.
But I noticed that javadoc does not care if the folder already exists or contains files.
So my solution is simple: generate the desired additional files in prepare-package, and the regular javadoc:jar task adds the regular javadoc and pacakges it nicely.
This will work as long as you don't intend to modify files generated by javadoc (which I, fortunately, don't - I only add additional documentation.
The resulting pom.xml is like this:
<plugins>
<!-- copy additional javadoc resources -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/apidocs</outputDirectory>
<resources>
<resource>
<directory>${basedir}/src/main/javadoc</directory>
<excludes>
<!-- overview.html is integrated by javadoc -->
<exclude>${basedir}/src/main/javadoc/overview.html</exclude>
</excludes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<!-- Generate additional files for javadoc -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.3.2</version>
<executions>
<execution>
<id>generate-extra-javadoc</id>
<phase>prepare-package</phase>
<goals>
<!-- java is okay, but you only can have one -->
<goal>exec</goal>
</goals>
<configuration>...</configuration>
</execution>
</executions>
</plugin>
<!-- Build JavaDoc -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.1</version>
<executions>
<execution>
<id>attach-javadocs</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
Eric,
If you are uncomfortable modifying the javadoc executable, another option is to break apart your javadoc call into 2 separate steps (javadoc and jar) and make your call between them by manipulating the Maven build lifecycle via <phase> tag:
phase: generate-sources => maven-javadoc-plugin:javadoc
phase: compile => exec-maven-plugin:java
phase: package => maven-javadoc-plugin:jar
note: use exec:java, not exec:exec to run java classes
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.9.1</version>
<executions>
<execution>
<id>generate-javadocs</id>
<phase>generate-sources</phase>
<goals>
<goal>javadoc</goal>
</goals>
</execution>
<execution>
<id>attach-javadocs</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.3.2</version>
<executions>
<execution>
<id>generate-nonstatic-javadocs</id>
<phase>compile</phase>
<goals>
<goal>java</goal>
</goals>
<configuration>
<mainClass>foobar.GenerateNonstatic</mainClass>
</configuration>
</execution>
</executions>
</plugin>
To answer your first question: Run a commandline command with the Exec-Maven-Plugin or use the Maven-Ant-Plugin and embed custom tasks.
Eric,
Your example is indeed helpful. Please do try to always include concrete examples as much as possible when asking the question.
The simplest approach would be to write your own Alternate Javadoc tool and pass that into Maven via the <javadocExecutable> tag. This example comes from the link above:
<project>
...
<reporting> (or <build>)
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>2.10.1</version>
<configuration>
<javadocExecutable>C:\jdk1.6.0\bin\javadoc.exe</javadocExecutable>
...
</configuration>
</plugin>
...
</plugins>
</reporting> (or </build>)
...
</project>
Hope that helps.
I'm using the exec-maven-plugin to execute a batch file with maven. I had it running during the package phase, but I need it to run earlier. The compilation phase would be fine.
The batch script generates a properties file that contains the svn version. When the phase is set to package, it looks like is does this after it makes the war file. Too late for me.
However, in eclipse I get this error:
Plugin execution not covered by lifecycle configuration: org.codehaus.mojo:exec-maven-plugin:1.2.1:exec (execution: Version, phase: compile)
The relevant section of my pom.xml:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<id>Version</id>
<phase>compile</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>\my\path\version\version.bat</executable>
</configuration>
</plugin>
First, is exec-maven-plugin still the right tool?
Second, can it be run during an earlier phase than package? Is this documented anywhere? The mailing list archive links on the exec-maven-plugin project page are out of date.
The problem is not with exec-maven-plugin but with m2e plugin which doesn't know what to do with exec-maven-plugin. The simplest way to fix the problem is to ignore that plugin during build within Eclipse (right click on the problem and use a proposed solution). Command-line invocation will still run the batch.
If you wish m2e can be configured more sophisticately. Take a look on the snippet from one of my projects:
<pluginManagement>
<plugins>
...
<!-- The following plugin is solely to make Eclipse happy, it's not executed during regular build -->
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>com.googlecode.cmake-maven-project</groupId>
<artifactId>cmake-maven-plugin</artifactId>
<versionRange>[2.8.11-b4-SNAPSHOT,)</versionRange>
<goals>
<goal>generate</goal>
<goal>compile</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute />
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
Also you may run virtually any goal of any plugin during any phase or completely disable its execution. Here I disable default-deploy of the maven-deploy-plugin and assign a customized goal deploy-file to the deploy phase:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<version>2.5</version>
<executions>
<execution>
<id>default-deploy</id>
<phase>none</phase>
</execution>
<execution>
<id>versioned-deploy</id>
<goals>
<goal>deploy-file</goal>
</goals>
<phase>deploy</phase>
<configuration>
<file>${project.build.directory}/${project.build.finalName}.${project.packaging}</file>
<repositoryId>${project.distributionManagement.repository.id}</repositoryId>
<url>${project.distributionManagement.repository.url}</url>
<generatePom>false</generatePom>
<pomFile>${effective_dir}/pom.xml</pomFile>
</configuration>
</execution>
</executions>
</plugin>
There's a special mvn help:effective-pom command which allows you to understand what is the final configuration of a mavenized project.