Binary output and testing for Eclipse plugins - maven-2

I am developing an Eclipse plugin and I use maven to coordinate my source structure. In order to compile the plugin I use the tycho extension for maven. However, I was wondering how to execute unitests.
I want to use the surefire plugin for testing as I additionally use a sonar server for source code quality management. Unitests are applyed if I use eclipse-test-plugin as package target. However, I want to make use of the default surefire plugin for applying unitests.
Now I figured out that the src/test/java that contains my unittest packages is read and compiled correctly but written into the wrong output folder. I need to have the tests in target/test-classes. However they are compiled to target/classes.
As I am new to Eclipse plugin development and maven I could not find out how to write the tests to the correct output folder. I've already tried adding and and changing the build.properties of the eclipse-plugin project. It works also fine for other projects that aren't plugin projects and do not make use of tycho.
Any help appreciated.
Regards,
Florian

Unlike standard maven projects, the convention for eclipse plugins/OSGi bundles is to have tests reside in separate projects. This is because there is no such thing as a maven dependency scope "test" in OSGi.
Thus keeping your tests inside the same project as your code under test would force you to mix up test code/dependencies an productive code/dependencies.
As you mentioned, Tycho provides a separate maven packaging type "eclipse-test-plugin" which you should use for dedicated test plugins/fragments. See https://docs.sonatype.org/display/TYCHO/PackagingTypes
There is no support in Tycho for plain unit tests residing in the same project.

Related

Will intellij idea "mvn install" automatically when make the project?

I'd like to know what will Intellij IDEA do with my Maven project when I click "build the project"?
How will Intellij build the project with Maven?
Intellij IDEA will not automatically do a make install when you do a Build Project. In order to do that, proceed as follows:
Under Maven Projects tab (usually on the right hand side), select the goals you want Intellij to run after a Build -> Make Project and then right click and select the trigger (for instance in the above snapshot, the trigger was chosen as 'Execute After Make'. You can choose whatever you wish).
After doing this a Build -> Make Project will run a mvn clean install as well.
IntelliJ's build system refers to the Maven ecosystem for some hints, but at the end of the day it is a separate build system.
In IntellIJ, you have a Project, with many Modules. These are both IntelliJ concepts.
An IntelliJ Module has a responsibility to understand what are its dependencies and libraries. This can be done purely with IntelliJ semantic, or IntelliJ can allow some other build system to declare the dependencies and libraries. That is to say: the IntelliJ Module can be based on a Maven pom.xml or Gradle's build.gradle.
When you click "Make" on an IntelliJ Java Module: IntelliJ will check which libraries your Module asks for, and also resolve the dependencies of your Module to work out which libraries its dependent Modules ask for.
Once the libraries are known: IntelliJ will invoke Javac or the Eclipse Compiler (whichever you've configured as your Java compiler) with all those libraries on the classpath. And it will output a jar, not a Maven artefact.
IntelliJ Make will not run a mvn compile or similar (unless you configure it to explicitly, as per #Ashutosh Jindal's answer.
Why would IntelliJ use its own, separate build system, when you've provided an authoritative definition for how you'd like to build your project? I can imagine various reasons:
Maven generally just outputs an artefact (sources and binary jars, and a pom.xml), whereas IntelliJ needs additional semantic and indexes to provide all its IDE intelligence. It makes sense to perform the indexing process alongside the compile, since: if you do the compile incrementally, you can understand incrementally which indexes are dirtied also.
The IDE benefits from being involved in the compilation process. For example: IntelliJ can do "continue on error" builds using the Eclipse compiler. Additionally, the Eclipse compiler can be used to compile only those files which have changed (IDEs watch you as you code, so they know very well which files are dirtied). I have heard that Maven does incremental compile, but I don't know how its performance compares.
In order to support a variety of build systems (Ant, Maven, Gradle): the easiest engineering choice for IntelliJ is to rely on the minimum possible amount of domain-specific semantic, and use that to inform one IntelliJ-specific build system. This allows them to re-use a large amount of code, and have few domain-specific differences.

Getting contents and natures of all projects in a Maven build

Currently I'm working on a Maven plugin that should generate files in all projects (OSGi bundles) that have a certain Eclipse project nature.
How can I access the contents of the projects included in the build and the project natures by using the Maven API?
Maven is a standalone build tool, not an Eclipse plugin. You cannot access Eclipse project settings from core Maven API.
Eclipse supports Maven with the M2E Eclipse plugin. It is possible to write M2E extensions and in the extension you can query the project natures via the functions of AbstractProjectConfigurator class.
However, M2E extensions will not run when you compile your code in the command line. I suggest that you choose one of the followings:
Write an Eclipse plugin that generates the source code into the src folder of the maven project. Code generation should be started by the user manually (selecting a context menu in the project or something).
Avoid using Eclipse project natures and solve your questions based on analyzing the source and pom of your project.
If you need to react on certain aspects in the source code like it looks from the thread with Balazs then you can simply write an ordinary maven plugin and include it in the parent pom. It will then run in every project and can analyze the code and react based on it.

How do I build a Play project with Hudson?

I have a project that's using the Play framework, and the corporate standard is that all projects should be built by Hudson. However, I cannot find out how to do this, as Hudson does not follow any Java standards, and requires the framework installed at the computer it runs on. I have tried to build the project with Maven (if I had managed this, adding it to Hudson should be quite simple), but I have failed to make it work. I tried the Play Maven module, but Maven claims it does not find the external repo that is listed (http://nexus.infin-it.fr/content/groups/public). This might be because I am behind a firewall. I also tried the recipe listed here, but the local maven build fails because it is unable to find org.playframework:play:1.1:jar.
Has anyone done this and can provide a howto?
It can be done without installing the Play framework on the Hudson server, but it is quite complicated:
Put the play libraries (play.jar and its dependencies) in a Maven repository
Create a pom.xml for your project, configured with:
theses libraries as dependencies
your project specific dependencies (project lib directory)
the java sources folder of your project (in the maven-compiler-plugin): "app"
If your project is simple (no module dependencies), this pom allows you to build the play project java sources using Maven.
If your project has module dependencies, you will have to add the dependencies jar in your pom dependencies.
To do that, you will have to create jar files from the modules if they don't have packaged jars (to get the "CRUD" class of the CRUD module for example).
You can find some help on this page I wrote :
http://blog.infin-it.fr/2010/12/15/play-framework-integration-continue-retour-dexperience/
Even if it's in French, I put my Ant stuff and the Play's pom I wrote.
At work we managed to integrate our Play applications with Bamboo.
It should not be difficult with my files.
Just looked at the repository, that you linked (http://nexus.infin-it.fr/content/groups/public). And guess what, I found the play-1.1.jar. However, the artifact ID is: org.play:play:1.1:jar and not org.playframework
In theory, you could put the full Play zip on your build or in in your repository, and then use Hudson to kick off an Ant script to download Play to the Hudson agent, unzip it, and then run commands on it. It's a little clunky, but it should work.

How well does m2eclipse deal with maven plugins?

In general, how well does m2eclipse deal with Maven plugins that modify or amend lifecycle phases?
In particular, I have a project that has a maven-clean-plugin extension to remove an extra generated directory (not in target/) using the configuration filesets tag. This works when running mvn at the command line but not when doing a clean in Eclipse. Is there any way to get m2eclipse to process that plugin?
Another example is flexmojos; there's a lot that can be configured with the flexmojo plugin but those parameters don't seem to get imported by m2eclipse.
Is the integration solely ad-hoc? If m2eclipse embeds Maven, why can't the plugins be executed directly using the underlying pom.xml configuration?
In general, how well does m2eclipse deal with Maven plugins that modify or amend lifecycle phases?
Decently, to my experience. At least for plugin bound to phases from the default lifecycle.
In particular, I have a project that has a maven-clean-plugin extension (...). This works when running mvn at the command line but not when doing a clean in Eclipse. Is there any way to get m2eclipse to process that plugin?
What the clean plugin "extension" is doing and what you're doing (calling mvn clean from Eclipse? calling Project > Clean?) is unclear - at least for me. But maybe have a look at MNGECLIPSE-823 or MNGECLIPSE-156. And don't hesitate to clarify :)
Another example is flexmojos; there's a lot that can be configured with the flexmojo plugin but those parameters don't seem to get imported by m2eclipse.
I don't do flex so the above is too vague for me. But providing a more concrete example might help.

How do I combine library code and a maven plugin in same project?

Can I make a single maven project that can be included as a dependency (to reference Java classes inside) and executed as a plugin?
I'm working on a library to help with hosting GWT on a LAMP stack. For someone to use this, they need to extend some Java classes (so it must be a dependency) and they need to invoke a maven plugin (so it needs to be a plugin). The plugin code references the same Java classes, so if they are seperate projects, the plugin one must depend on the library one.
As is, I have the library as a normal maven project, and the plugin as a maven plugin that depends on the library. This means that to do a release, I have to release two different artifacts, and the dependent project must update both version numbers for both artifacts. It'd be nice to have a single project.
You'd be better of by doing the following
project for the jar, Foo:Foo.jar
project that uses Foo:Foo.jar as a
dependency that builds the plugin
Maven parent project that
builds 1&2
The directory structure would look like this
\project\pom.xml
\project\foo\pom.xml
\project\foo\src\main\java\foo.java
\project\plugin\pom.xml
\project\plugin\src\main\resources
\project\plugin\src\main\java
From \project you can do a mvn clean package to build \project\foo\target\foo.jar and \project\plugin\target\plugin.jar
Hope this helps.
If you create a maven plugin it still has a artifactId/groupId/version. There's no reason it can't be references both in your section and in your section. On the other hand, if thats ugly, why not just make a library with the common code that both your main project and your maven plugin project depend on?
EDIT:
Sorry, wasn't clear on the second part. Look into composite maven projects, where there is a top level pom that defines a number of child modules. In this case, the maven plugin and the common library code could be separate children producing separate artifacts, but you only need one version number and one release command executed from the top level. I haven't done this but there are any number of open source projects that do. its often used as an idiom to put testing code into a single module that can be referenced by all the others, without having it go out in any distributable jar.
The best practice is to not do what you're suggesting. Examples of this include PMD, BND, JUnit/TestNG, and so on - no serious projects seem to package the maven plugin with the library proper.
One way to get both alternatives is to use maven assemblies to have two seperate maven projects for each the library proper and the plugin and then a separate packaging as a jar containing the classes from both.