Maven keeps changing project settings - How to edit effective pom file? - eclipse

I told Eclipse to use the output folder
E:\java\<project>\<project>-parent\<project>-web-server\war\WEB-INF\classes
but every Maven update changes it back to the value as stored in the effective pom:
<plugin>
<artifactId>maven-site-plugin</artifactId>
<version>3.3</version>
<executions>
<execution>
<id>default-site</id>
<phase>site</phase>
<goals>
<goal>site</goal>
</goals>
<configuration>
<outputDirectory>E:\java\<project>\<project>-parent\<project>-web-server\target\site</outputDirectory>
<reportPlugins>
<reportPlugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-project-info-reports-plugin</artifactId>
</reportPlugin>
</reportPlugins>
</configuration>
</execution>
<!-- .... -->
</plugin>
The file is not editable and I don't really know how this file gets generated and/or how to change it. How can I manipulate the values in the effective pom file?
Edit:
Another thing you've already noticed are those absolute paths I'd like to get rid of. So as a side-quest: How would I do that?

You have to modify your maven configuration to use the desired output folder.
The effective pom you see is the "calculated" pom and hence not editable. You can edit the pom file by clicking on the pom.xml tab (just next to the effective pom tab)

Edit the pom file and add the folders there. The effective POM file is, as you said, autogenerated on each build, thus also the absolute paths. In the pom file itself you of course have no absolute paths.
To change the output folder to the folder "war" in your project, add the following to your pom.xml:
<build>
<outputDirectory>${project.basedir}/war</outputDirectory>
</build>
You can see all configuration properties in the Maven manual: https://maven.apache.org/pom.html

Related

How to use build-helper-maven-plugin to create extra directory?

I have a Java Maven project with the following structure. (This is a logical structure, not necessarily the exact directory structure.)
Project
|-Submodule
| |-src/main/java
| |-src/main/resources
| |-src/test/java
| |-src/test/resources
| `-pom.xml
`-pom.xml
In accordance with (my understanding of) Maven standards, the parent pom references the submodule in it's <modules> tag, and the submodule pom references the parent pom as it's <parent>.
Now, my goal is to use Maven to add two new source folders to the submodule, namely src/integrationTest/java and src/integrationTest/resources. I want Maven to "know about" these two folders so that I can execute the tests therein using my Maven testing plugin, maven-pmd-plugin. And I want Eclipse to "know about" these two folders so that they display correctly in Eclipse's graphical Project Explorer.
I was told that the build-helper-maven-plugin plugin could be used to create these additional directories that I needed. So I added the following configuration to my submodule pom:
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<id>add-integration-test-sources</id>
<phase>generate-test-sources</phase>
<goals>
<goal>add-test-source</goal>
</goals>
<configuration>
<sources>
<source>src/integration-test/java</source>
</sources>
</configuration>
</execution>
<execution>
<id>add-integration-test-resources</id>
<phase>generate-test-resources</phase>
<goals>
<goal>add-test-resource</goal>
</goals>
<configuration>
<resources>
<resource>
<directory>src/integration-test/resources</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
When I rebuilt the project, Maven didn't generate the directories I wanted. So I took the plugin configuration out of my submodule pom and put it in my parent pom instead. Maven still didn't generate my directories.
At this point, I don't know how to get this plugin working. I'm trying to follow other online tutorials, but I must be doing something wrong. Could anyone explain which pom file is intended to configure build-helper-maven-plugin? And how do I configure Eclipse to display the new Maven project structure correctly?
Thanks for the help!
khmarbaise's comment made me realize my mistake, although I didn't take his advice.
The build-helper-maven-plugin configuration should go in the submodule pom (not the parent pom) where I originally had it. But Maven will not create these directories for you, you create the directories and then Maven uses them.
Once Maven is using your new directories, Eclipse displays them just fine.

GWT does not use resource properties file from target, but the once in src/main/resources. How to make it with placeholders?

I have gwt web project, which must use application.properties (on client side) loaded as TextResource in the code. Everything works fine, but now i want to centralize all properties values in maven pom.xml. So i made application.properties with placeholders like key1=${param1} and in the pom.xml i configured property param1Value
So, what happening is that maven replaces the placeholders in application.properties in target dir, but it seems that gwt compiler uses the application.properties file from src/main/resources. I checked the compiled js files and i there i can see that the placeholder is not replaced with its value from the pom.xml (target's application.properties is correct).
UPDATE:
The problem is that, the properties file I am filtering is a gwt messages resources bundle file and from what I saw, maven creates a "generated" folder and puts a generated java file based on the properties file found in the root project sources folder and not in the target folder. After that, it incorporates it in the javascript general file.
This means I have two possibilities:
1) tell the resources plugin to overwrite the properties file located in the sources folder (I am not cool with that because I will certanly have problems on the next subversion update)
2) tell gwt-maven-plugin to seek the properties file in the target/classes folder which I think it is impossible
What do you think ?
I resolved the same problem by using resources:copy-resources execution and build-helper plugin.
In particular, configure the resources plugin:
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<executions>
<execution>
<id>filter-sources</id>
<goals>
<goal>copy-resources</goal>
</goals>
<phase>generate-sources</phase>
<configuration>
<outputDirectory>${project.build.directory}/gwt-extra</outputDirectory>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/filtered-sources</directory>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
and include it using build helper:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>add-source-gwt</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/gwt-extra</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
I managed to use maven filtering on properties files used in GWT compilation.
I use the com.google.gwt.i18n.client.Constants interface.
It allows to instanciate an interface that extends Constants, with methods returning values taken from a properties file.
That properties file can be process by maven filtering.
It's really easy to do :
declare an interface extending Constants : XxConstants
create a properties file XxConstants.properties in src/main/resource in the same package as your interface
activate maven resources filtering so XxConstants.properties is filtered
when GWT is compiling (with gwt-maven-plugin), it will generate an instance of XxConstants using the filtered properties file.
in your gwt code, create an instance of XxConstants with GWT.create or with gin injection
call the methods to get the property values
One caveat : filtering is not working in gwt dev mode
Result can be check in the target.generated folder whiwh will contained the java implementation of the interface with the filtered properties used.

What is the correct way to specify a main class when packaging a jar using m2eclipse?

Problem:
I'd like to specify the main class in a jar file that I am packaging using m2eclipse: [right-click] -> Run As -> Maven package. I'm still learning Maven and from what I've read, the straight-up way of accomplishing this task is to add a stanza to the pom.xml.
Here are examples I found when I was researched this issue:
Cannot make executable jar using m2eclipse
http://docs.codehaus.org/pages/viewpage.action?pageId=72602
My question is this: is it okay to manually edit the pom.xml file outside of Eclipse/m2eclipse using a text editor, or should I be doing this configuration using the m2ecplise GUI? There are several tabbed dialog boxes that seem like they might be likely candidates for this task, like "Plugins" and "Build". I looked through Sonatype's documentation and couldn't find any detailed instructions on how to accomplish what I need to do.
I'm a little hesitant to edit the pom.xml manually because I notice the "Effective POM" already has a lot of extra stuff in it, including the plugin definition that needs to have added to it:
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
If I understand correctly, the Effective POM needs to be changed so that the plugin is configured like this:
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<executions>
<execution>
<id>default-jar</id>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<mainClass>[name of main class]</mainClass>
<packageName>[package name]</packageName>
</manifest>
<manifestEntries>
<mode>development</mode>
<url>${pom.url}</url>
</manifestEntries>
</archive>
</configuration>
</plugin>
Is this right? And if so, do I do this through m2eclipse or should I just copy all the extra Effective POM stuff and paste it into the actual pom.xml using a text editor?
Thanks to anyone who can shed some light.
UPDATE: I went ahead and manually edited the pom.xml file in a text editor. When I viewed Effective POM in m2eclipse it displayed everything that I put in (I assume). I built the jar and the main class was correctly set.
This seems like a hack to me though. Does anyone know if there's a way to do this configuration using m2eclipse itself? I checked the m2eclipse tabs and nothing seemed to have been updated as a result of my manual edits of pom.xml (other than the Effective POM tab).
m2eclipse doesn't do everything for you, i.e. there isn't a pretty UI tab for handling everything.
My team is most comfortable with editing the POM manually, and using the other tabs for verification (like Effective POM view).

How to debug an OSGi Bundle inside eclipse using maven structured project

I have a maven project which library should also be an OSGi bundle with an
declarative service. I added the OSGI-INF folder with the service.xml inside
src/java/resources which will be added to the jar. But: When I start the project as equinox project, where I want to check if the service is loaded, I get the error that the OSGI-INF/service.xml can't be found. I guess eclipse won't add the resources folder to the classpath when starting.
BTW: The MANIFEST-MF is in the root folder and the pom.xml contains the following text:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifestFile>META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
Has anbody a good idea how to tell eclipse where to find the metadata files? I'm using m2eclipse if this is relevant.
Thanks in advance
Hannes
I've the same issues but I've manually tweaked my POM.xml for copying the generate target/classes/META-INF/** stuff (MANIFEST.MF, property files, spring XMLs, ...) into the project ROOT folder (which Eclipse PDE expects):
<!--
We copy all stuff from target/classes/META-INF into META-INF/ in order
to keep Maven output with PDE.
-->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<id>synch-pde-metadata-from-maven</id>
<phase>package</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/META-INF</outputDirectory>
<resources>
<resource>
<directory>target/classes/META-INF</directory>
<filtering>false</filtering>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<!--
We delete all stuff from the root bundle's META-INF
-->
<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.4.1</version>
<configuration>
<filesets>
<fileset>
<directory>META-INF</directory>
<includes>
<include>**/*</include>
</includes>
<followSymlinks>false</followSymlinks>
</fileset>
</filesets>
</configuration>
</plugin>
(I also clean up things when mvn clean is called) It is not really efficient but it works.
Ps: you may have to right-click on the project and make it a plug-in project in order for this to work.
The Problem is that Eclipse needs that OSGI-INF (and also META-INF) Folder in root.
I have found a link on how to probably solve the problem.
https://www.nuxeo.com/blog/working-with-osgi-and-maven-in-eclipse/
Basically they put the OSGI-INF and META-INF Folders into src/main/resources
Then they set the src/main/resources Folder as root of the OSGI project. So that Eclipse has both Folders at root.
To have Soure Files also available they added a Linked Resources to src/main/java by adding an entry to the .project File
<linkedResources>
<link>
<name>src</name>
<type>2</type>
<locationURI>PARENT-1-PROJECT_LOC/java</locationURI>
</link>
</linkedResources>
Now you just need to copy the .prject and .classpath Files into src/main/resources (your new root) and everything should be working.
By the time of this writing i didn't test this on my own but will do so in the near future.

How do I get Eclipse to resolve classes generated with Maven 2?

I'm using Google Protocol Buffers to generate some Java classes for my project. Using Maven 2 and its "antrun" plugin, these classes are freshly generated before compile, output to target/generated-sources and put on the classpath during the build. So building the project from the POM is no problem.
However, Eclipse doesn't know how to resolve the generated class, because the folder it's in doesn't seem to be on the IDE's classpath during development. I'm using m2eclipse and have it manage dependencies for me, so I had expected Maven to take care of this.
How can I get IDE support (code completion etc.) for the generated code?
m2eclipse supports this. First, add the path to your build path:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.8</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/java/</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
Second, add support for that to m2e:
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<versionRange>[1.0,)</versionRange>
<goals>
<goal>parse-version</goal>
<goal>add-source</goal>
<goal>maven-version</goal>
<goal>add-resource</goal>
<goal>add-test-resource</goal>
<goal>add-test-source</goal>
</goals>
</pluginExecutionFilter>
<action>
<execute>
<runOnConfiguration>true</runOnConfiguration>
<runOnIncremental>true</runOnIncremental>
</execute>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
The second step might not be necessary, if your eclipse installation has installed the "org.eclipse.m2e.discovery.lifecyclemapping.buildhelper.xml" plugin. This plugin is available via Window -> Preferences -> Maven -> Discovery. Currently, that does not work here at Eclipse Kepler, therefore, I fetched the JAR (linked from the xml shown in the Catalog URL) and extracted the fragments from org.eclipse.m2e.discovery.lifecyclemapping.buildhelper.xml by hand.
m2eclipse doesn't support this. You must manually add the folder target/generated-sources as a source folder. When you tell m2eclipse to "Update Project Configuration", this will be overwritten and you have to restore it.
Also, make sure that Eclipse looks for changes in the workspace.
There might be some issues, though. Eventually, you'll run into errors that some class can't be compiled because some other class can't be resolved. Code completion will work, though. The root cause of this issue is that Eclipse gets confused when Maven changes class files in target.
To solve this, you must tell Eclipse to compile to a different place than Maven.
What you should see in your project explorer is a container named "Maven Dependencies" in place of the usual "Referenced libraries". This means m2eclipse is managing your build path.
In my case, to achieve this, I checked "Include Modules" and unchecked "Skip Maven compiler plugin when processing resources" on the "Maven" section of Project->Properties.
Personally I resolved this problem by setting up the generated classes as a seperate project and made it a dependency in my main (non-generated) project. I was using wsdl2java to generate webservice classes so the "source" in my sub-project was the wdsl and xsds. Worked well even when the wsdl was changing regularly.
I had this issue with code generated using Maven and wsdl2java and here's what I did in Eclipse Juno to resolve it. Assume my project is named project1:
Right-click project1 and select Properties
Choose Java Build Path from the left and select the Libraries tab
Click Add Class Folder
Select the bin directory and click OK (project1/target/generated-sources/bin)
Click OK and Refresh the project
As an added bonus you can also attach the source code:
Click the arrow next to the new class folder you just created
Click on Source attachment
Click the Edit button
Set the Path to /project1/target/generated-sources/axis2/src
Click OK
Right-click project and select Properties
Choose Java Build Pathfrom the left and select the Source tab
Click Add Folder
Select the bin directory and click OK
(project/target/generated-sources/xxxx) Click OK and Refresh the project
How can I get IDE support (code completion etc.) for the generated code?
Typically I would add the m2e lifecycle-mapping plugin to the pom.xml file as described in #koppor's answer. However adding per-eclipse code to my pom.xml files is not an option at work which is mostly an IntelliJ shop.
My solution first adds the build-helper-maven-plugin to the pom.xml which works fine from the command line but not in eclipse.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>${project.build.directory}/generated-sources/</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
To fix eclipse I installed the Apt M2E Connector from the Eclipse Marketplace. I think things started working right after I restarted and then rebuilt all of my projects. I now see the following in my source dirs:
src/main/java
target/generated-sources
...
Feature!
Did you try to refresh the Eclipse project?
(source: oyvindhauge.com)
When an external tool generate new files or updates old ones, Eclipse will not be able to detect the change until the next request.
Another option would be to define a new Custom builder, specifying for that builder to "refresh resources upon completion":
alt text http://www.cs.lth.se/EDA180/2005/Verktyg/eclipse_refresh.gif
Worked for me (But you will to have to follow this every time so you can add this path in pom.xml)
Right click on your project > Build Path > Configure Build Path
In sources tag, click on [Add Folder] button
Check target/generated-sources/annotations
To generate Java source files from .proto files use Protocol Buffers Plugin which works out-of-the-box in eclipse Oxygen.
Basic usage (see here for detailed description):
make sure that native protoc compiler is installed on your system
update your pom.xml file:
make sure you use at least Java 6 (Java 7+ is recommended)
add plugin invocation
add the corresponding dependency for com.google.protobuf:protobuf-java
put your .proto files inside project's src/main/proto directory
update the project (via Maven -> Update project...)
Example pom.xml:
<project>
...
<build>
<plugins>
<!-- Require at least Java 6 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<!-- Generate .java files from .proto definitions -->
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.1</version>
<configuration>
<protocExecutable>/usr/local/bin/protoc</protocExecutable>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
...
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.5.1</version>
</dependency>
...
</dependencies>
...
</project>
Some additional notes:
if protoc executable is in the PATH the protocExecutable configuration entry can be omitted
test-only protobuf message definitions can be put into project's src/test/proto directory
I recommend installing Protocol Buffer Descriptor Editor (marketplace link)
Good luck!