How To Build Child Modules In Tycho - tycho

I have a multi-module Tycho build with a target definition file. The target definition is defined in it's own project (ID: org.acme.project.target, packaging type: pom) like this:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>1.3</version>
<executions>
<execution>
<id>attach-artifacts</id>
<phase>package</phase>
<goals>
<goal>attach-artifact</goal>
</goals>
<configuration>
<artifacts>
<artifact>
<file>platform_rcp.target</file>
<type>target</type>
<classifier>platform_rcp</classifier>
</artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
And the Maven parent refers to this target platform like this:
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>target-platform-configuration</artifactId>
<configuration>
<resolver>p2</resolver>
<target>
<artifact>
<groupId>${project.groupId}</groupId>
<artifactId>org.acme.project.target</artifactId>
<version>${project.version}</version>
<classifier>platform_rcp</classifier>
</artifact>
</target>
</configuration>
</plugin>
This setup works as long as I build the parent project. When I build one of the child modules, even if this project duplicates the reference to the target platform OR even when I build the parent with mvn install -pl org.acme.project I get the following exception:
[ERROR] Internal error: java.lang.RuntimeException: Could not resolve target platform specification artifact myGroup:org.acme.project.target:target:platform_rcp:2.3.0-SNAPSHOT -> [Help 1]
org.apache.maven.InternalErrorException: Internal error: java.lang.RuntimeException: Could not resolve target platform specification artifact myGroup:org.acme.project.target:target:platform_rcp:2.3.0-SNAPSHOT
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:121)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:862)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:286)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:197)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
Even the Tycho example doesn't work for me, but brings the same error message (Could not resolve target platform specification artifact example.group:mars:target:1.0.0-SNAPSHOT).
I thought this question was similar, but my setup is exactly what is said to work in the answer.
What did I do wrong?
(The actual problem in question is that Eclipse Mars can't run integration tests, so I can only use Tycho to run them, which needs a long time when Tycho builds all modules.)

even when I build the parent with mvn install -pl org.acme.project I get the following exception:
Have you tried prepending the target platform project to the list of -pl arguments: mvn install -pl :mars,org.acme.project
I use this all the time.

Related

MAVEN: No plugin found for prefix 'dependency' in the current project and in the plugin groups [org.apache.maven.plugins, org.codehaus.mojo]

[ERROR] No plugin found for prefix 'dependency' in the current project
and in the plugin groups [org.apache.maven.plugins, org.codehaus.mojo]
available from the repositories [local
(C:\Users\mdhore.m2\repository), central
(https://repo.maven.apache.org/maven2)] -> [Help 1]
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.0.2</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<!-- configure the plugin here -->
</configuration>
</execution>
</executions>
</plugin>
</plugins>
according to this you have to provide group and artifact id. I run mvn dependencies:tree like the following and it worked.
mvn org.apache.maven.plugins:maven-dependency-plugin:2.10:tree -Dverbose=true
I got this error when I forgot to add this parameter. I have to add to each of my Maven comamnds to autheticate with my Maven remote repository.
-Djava.net.ssl.trustStore=cacerts.jks. If you don't normally add a parameter like this you probably have another issue.
I have also encountered the same issue. I typed the wrong command mvn dependences:resolve, the correct one is mvn dependency:resolve.
I got the same error and in my case I didn't have the POM file in the same directory I was in.
make sure there is no import error anywhere in your code then run mvn dependency:tree the error will be gone. I assume you are using mvn and you have some import issue somewhere in your project.

Dependencies In Same Reactor

I have a very simple Tycho reactor with two modules: one is a standard Maven project with this addition to make it a bundle:
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<id>default-bundle</id>
<phase>package</phase>
<goals>
<goal>bundle</goal>
</goals>
<configuration>
<instructions>
<Export-Package>org.acme.jar</Export-Package>
</instructions>
<manifestLocation>META-INF</manifestLocation>
</configuration>
</execution>
</executions>
</plugin>
The second is a Tycho project that has a dependency to the above JAR in the MANIFEST.MF.
If I start the build, I get the following exception:
[ERROR] Cannot resolve project dependencies:
[ERROR] Software being installed: plugin 0.0.1.qualifier
[ERROR] Missing requirement: plugin 0.0.1.qualifier requires 'bundle org.acme.jar 0.0.1' but it could not be found
Which is really weird, because the bundle is in the same reactor.
But no worries, I can just add the Maven dependency, too:
<!-- parent pom.xml -->
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>target-platform-configuration</artifactId>
<version>0.26.0</version>
<configuration>
<pomDependencies>consider</pomDependencies>
</configuration>
</plugin>
<!-- plug-in pom.xml -->
<dependencies>
<dependency>
<groupId>org.acme</groupId>
<artifactId>jar</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
Still I get the same exception, which is weird because the documentation claims: Maven resolves the GAV dependencies according to the normal Maven rules.
That's just not true. Evidently org.acme.jar doesn't get resolved. Or maybe Tycho fails to see that it's a bundle.
The JAR module is an API project used for server side components, and we want to drop SWT / Tycho in the long run, so it's not an option to make org.acme.jar an Eclipse plug-in.
How do I define dependencies in the same reactor for Tycho?
I’m afraid that what you ask for is currently not possible. The Tycho Wiki documents this limitation in the dependency on pom-first artifacts HOW-TO.
That being said, if you really want your whole build (maven-bundle-plugin and Tycho parts) to run with a single mvn clean install, then using the maven-invoker-plugin at the end of the “plain Maven” build to fork a “Tycho build” should work. It’s a rather cumbersome workaround, however (example on Github).

Build local eclipse plugins using tycho pointing to local p2 repository

I am creating some Eclipse plugin and features that require third-party plugins and features. In order to include these dependencies into my project, I created a p2 layout repository.
Note: My p2 artifacts are not Maven project... However, I am using Maven style building. Here is the pom.xml for the p2 repository
<properties>
<tycho-version>0.18.0</tycho-version>
</properties>
<repositories>
<repository>
<id>eclipse-platform-m6</id>
<layout>p2</layout>
<url>http://download.eclipse.org/eclipse/updates/3.8</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho.extras</groupId>
<artifactId>tycho-p2-extras-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>publish-features-and-bundles</goal>
</goals>
<configuration>
<compress>false</compress>
<artifactRepositoryLocation>/mypath/target/repository</artifactRepositoryLocation>
<metadataRepositoryLocation>/mypath/target/repository</metadataRepositoryLocation>
<sourceLocation>/mypath/src</sourceLocation>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-repository-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>verify-repository</goal>
<goal>archive-repository</goal>
</goals>
<configuration>
<compress>false</compress>
<includeAllDependencies>true</includeAllDependencies>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-publisher-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<publishArtifacts>true</publishArtifacts>
</configuration>
</plugin>
<plugin><!-- enable the Tycho build extension -->
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-maven-plugin</artifactId>
<version>${tycho-version}</version>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
The above builds successfully, and creates (and verifies) a p2 repository. I get following structure in my target/ directory of the project
- Project
..
..
- target
- p2agent
- org.eclipse.equinox.p2.core
- org.eclipse.equinox.p2.engine
- repository
- features
- plugins
artifacts.xml
content.xml
<projectname>-<version>.zip <!-- This contains same things as repository directory here -->
Now, I use Tycho for building my plugins and features and refer the p2 repository I created above. I have following project structure for my plugins and features
- bundle.parent
- bundle.mainplugin
- bundle.mainplugin.test.fragment
- bundle.mainplugin.feature
Here is my bundle.parent pom.xml
<repositories>
<repository>
<id>eclipse-platform-m6</id>
<layout>p2</layout>
<url>http://download.eclipse.org/eclipse/updates/3.8</url>
</repository>
<repository>
<id>third-party-eclipse-plugins</id>
<layout>p2</layout>
<url>file:///.../target/repository</url>
</repository>
</repositories>
<modules>
<module>../bundle.mainplugin</module>
<module>../bundle.mainplugin.test.fragment</module>
<module>../bundle.mainplugin.feature</module>
</modules>
<build>
<plugins>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-maven-plugin</artifactId>
<version>${tycho-version}</version>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
Finally, I run goals mvn clean install on the parent pom.xml. Unfortunately, mvn-compile throws compilation issues when classes in my plugin extend some of the classes in plugins. (The classes are also required at run-time). Here is the error:
org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.eclipse.tycho:tycho-compiler-plugin:0.18.0:compile (default-compile
) on project <Project Name>: Compilation failure
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:213)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:153)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:145)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:84)
at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject(LifecycleModuleBuilder.java:59)
at org.apache.maven.lifecycle.internal.LifecycleStarter.singleThreadedBuild(LifecycleStarter.java:183)
at org.apache.maven.lifecycle.internal.LifecycleStarter.execute(LifecycleStarter.java:161)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:320)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
at org.apache.maven.cli.MavenCli.execute(MavenCli.java:537)
at org.apache.maven.cli.MavenCli.doMain(MavenCli.java:196)
at org.apache.maven.cli.MavenCli.main(MavenCli.java:141)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced(Launcher.java:290)
at org.codehaus.plexus.classworlds.launcher.Launcher.launch(Launcher.java:230)
at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode(Launcher.java:409)
at org.codehaus.plexus.classworlds.launcher.Launcher.main(Launcher.java:352)
Caused by: copied.org.apache.maven.plugin.CompilationFailureException: Compilation failure
at copied.org.apache.maven.plugin.AbstractCompilerMojo.execute(AbstractCompilerMojo.java:442)
at org.eclipse.tycho.compiler.AbstractOsgiCompilerMojo.execute(AbstractOsgiCompilerMojo.java:239)
at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:101)
at org.apache.maven.lifecycle.internal.MojoExecutor.execute(MojoExecutor.java:209)
... 19 more
My Question:
From the compiler errors, I believe Tycho is somehow not making these third-party artifacts available to my classes for which there is a compiler error. Is there a way to determine if my plugin classes exist in the Tycho classpath?
UPDATE
Checked availability of third-party bundles that I want to be available in Tycho reactor from this location
java -jar /home/.../eclipse-3.8.2/plugins/org.eclipse.equinox.launcher_1.3.0.v20120522-1813.jar -debug -consolelog -application org.eclipse.equinox.p2.director -repository file:///home/../target/repository -list
All third-party bundles showed up successfully.
Sebastian Zarnekow's answer gave me a hint.
Error while building an xtext project with ant: Generation of the Grammar classes fails
As you can infer from the error message, maven fails to create language models from injection. The reason is explained in the link above:
Xtext uses the platform:/resource URI scheme of EMF.
The solution is you need to give EMFGenerator a new declaration of where the model directory should be. In **.mwe2 file, replace the following code
fragment = ecore.EMFGeneratorFragment auto-inject {}
with
fragment = ecore.EMFGeneratorFragment auto-inject {
javaModelDirectory = "/${projectName}/src-gen"
}
should do the trick.
for anyone who also runs into this problem, you can also try using:
${project.basedir}
So, say you have the following directories:
- projects:
- main-project
- local-repository
In the parent pom (i.e.: main-project/pom.xml) reference the local-repository, using a relative path, in the following way:
<url>file:${project.basedir}/target/repository</url>
Just replace :
<url>file:///.../target/repository</url>
by :
<url>file:<projectname>/deploy/target/repository</url>
(if your parent pom.xml is your root folder)

Maven test dependency in multi module project

I use maven to build a multi module project. My module 2 depends on Module 1 src at compile scope and module 1 tests in test scope.
Module 2 -
<dependency>
<groupId>blah</groupId>
<artifactId>MODULE1</artifactId>
<version>blah</version>
<classifier>tests</classifier>
<scope>test</scope>
</dependency>
This works fine. Say my module 3 depends on Module1 src and tests at compile time.
Module 3 -
<dependency>
<groupId>blah</groupId>
<artifactId>MODULE1</artifactId>
<version>blah</version>
<classifier>tests</classifier>
<scope>compile</scope>
</dependency>
When I run mvn clean install, my build runs till module 3, fails at module 3 as it couldn't resolve the module 1 test dependency. Then I do a mvn install on module 3 alone, go back and run mvn install on my parent pom to make it build. How can I fix this?
I have a doubt about what you are trying to do but but I'll assume you want to reuse the tests that you have created for a project (module1) in another. As explained in the note at the bottom of the Guide to using attached tests:
Note that previous editions of this guide suggested to use <classifier>tests</classifier> instead of <type>test-jar</type>. While this currently works for some cases, it does not properly work during a reactor build of the test JAR module and any consumer if a lifecycle phase prior to install is invoked. In such a scenario, Maven will not resolve the test JAR from the output of the reactor build but from the local/remote repository. Apparently, the JAR from the repositories could be outdated or completely missing, causing a build failure (cf. MNG-2045).
So, first, to package up compiled tests in a JAR and deploy them for general reuse, configure the maven-jar-plugin as follows:
<project>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Then, install/deploy the test JAR artifact as usual (using mvn install or mvn deploy).
Finally, to use the test JAR, you should specify a dependency with a specified type of test-jar:
<project>
...
<dependencies>
<dependency>
<groupId>com.myco.app</groupId>
<artifactId>foo</artifactId>
<version>1.0-SNAPSHOT</version>
<type>test-jar</type>
<scope>test</scope>
</dependency>
</dependencies>
...
</project>
Regarding to my comment to Pascals question i think i have found a stuitable answer :
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<goals>
<goal>test-jar</goal>
</goals>
<phase>test-compile</phase>
</execution>
</executions>
<configuration>
<outputDirectory>${basedir}\target</outputDirectory>
</configuration>
</plugin>
</plugins>
The main difference here as you see here is the <phase> tag.
I will create the test-jar and it will be available in the compile phase of the tests and not only after the package phase.
Works for me.

JAVA_HOME gets mangled by Maven

I'm retrofitting bunch of existing Java projects with unified Maven build. Since each project is mature and has established Ant based build all I'm using maven-antrun-plugin to execute existing build.xml as follows:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>compile</phase>
<configuration>
<tasks>
<ant antfile="build.xml" target="compile" />
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
When I run mvn compile build fails with this message:
[INFO] An Ant BuildException has occured: The following error occurred
while executing this line:
build.xml:175: Unable to find a javac compiler;
com.sun.tools.javac.Main is not on the classpath.
Perhaps JAVA_HOME does not point to the JDK.
It is currently set to "C:\Java\jdk1.6.0_13\jre"
What puzzles me is
I have JAVA_HOME=C:\Java\jdk1.6.0_13 as part of my environment setup and when mvn.bat is executed that is exactly value I'm getting, however as you see in the error message it comes up as C:\Java\jdk1.6.0_13\jre
If I run ant compile everything compiles just fine
Does it mean that perhaps maven-antrun-plugin does something like set JAVA_HOME=%JAVA_HOME%\jre? I searched my batch/build files I can't find where that change occurs
Thats the down side of external links in an accepted answer. Codehaus shut down and thus the solution is gone. For reference here's the content behind the link - you basically only need to copy the <dependencies>...</dependencies> block to your antrun plugin...
The maven-antrun-plugin runs ant with JAVA_HOME set to the jre subdirectory of the JDK, even if the JAVA_HOME for the overall run is a JDK.
There is documentation elsewhere about how to create a dependency at the project level for the JDK's tools.jar, but this does not help out antrun, which is a plugin.
The following profile does the job. The '..' in the path hauls up past the 'jre' directory to the lib directory.
<profiles>
<profile>
<id>tools.jar</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<dependencies>
<dependency>
<groupId>com.sun</groupId>
<artifactId>tools</artifactId>
<version>1.5.0</version>
<scope>system</scope>
<systemPath>${java.home}/../lib/tools.jar</systemPath>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</profile>
I was able to fix this by putting the following property definition in my ant build.xml file:
<property name="build.compiler" value="extJavac"/>