Maven copy src/main/resources/services folder to /META-INF - maven-2

EDIT
Ok I can be now more specific:
I have in my scr/main/resources a folder META-INF who contains services/javax.annotation.processing.Processor
My pom is still the same (with commented).
If I do "mvn clean install", the output jar will contains only the META-INF folder.
But if I rename the folder services, the output jar contains my classes and the META-INF folder with the new renamed folder and his content.
I have - I suppose - a easy question for regular maven2 users.
I have this simple pom for a simple subproject
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>aida</groupId>
<version>0.0.1-SNAPSHOT</version>
<artifactId>aida-annotationProcessors</artifactId>
<packaging>jar</packaging>
<name>AIDA Annotation Processors</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
<!-- <resources> -->
<!-- <resource> -->
<!-- <directory>src/main/resources/services</directory> -->
<!-- <targetPath>META-INF/services</targetPath> -->
<!-- </resource> -->
<!-- </resources> -->
</build>
<dependencies>
</dependencies>
</project>
My goal is simple:
I just want to copy my src/main/resources/services/javax.annotation.processing.Processor file in the {root}/META-INF/services folder of my generated jar.
But if I uncomment the resource part, my jar will contains only a META-INF folder without class!
Could you help me?

This is a bug/feature in the maven compiler plugin..
http://jira.codehaus.org/browse/MCOMPILER-97
A workaround is to disable annotation processing for the project containing the processor, -proc:none.

A more flexible solution would be to use an annotation processor for generating the services/javax.annotation.processing.Processor file, that way the classes are left intact and no extra work is required if the project depends on additional annotation processors.
META-INF/services generator is in main repo:
<dependency>
<groupId>org.kohsuke.metainf-services</groupId>
<artifactId>metainf-services</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>
Annotate the processors with #MetaInfServices - note that I had to manually supply the annotation with Processor.class, otherwise it generated META-INF/services/javax.annotation.processing.AbstractProcessor
import org.kohsuke.MetaInfServices;
#MetaInfServices(javax.annotation.processing.Processor.class)
public class SoapPropertyProcessor extends AbstractProcessor

Here are the instructions from Apache for how to do that, but it appears that you're doing it correctly. Take a look at that page and make sure you're not making some small error.

Related

How to add multiple source directories to pom.xml

I am getting package org.testng.annotations does not exist error when I am trying to compile multiple source directories using maven. I am running webdriver tests and all of my tests are importing import org.testng.annotations. I am using IntelliJ 12 and my src directory looks like this -
src
-->main
--> java
--> package1
--> file1.java
--> package2
--> file2.java
-->test
--> java
--> package1
--> file1.java
--> file2.java
--> package2
--> package3
--> package4
--> package5
--> package6
and the build plugin I am using in the pom.xml looks like this -
<?xml version="1.0" encoding="UTF-8"?>
project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>core-xxxxx</artifactId>
<groupId>core-xxxxx</groupId>
<version>1.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>tests</artifactId>
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-api</artifactId>
<version>2.32.0</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<directory>target</directory>
<outputDirectory>target/classes</outputDirectory>
<testOutputDirectory>target/test-classes</testOutputDirectory>
<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>src/main/java</source>
<source>src/test/java</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
why am I getting the org.testng.annotations not found error?
The default layout for a maven project is the following:
src
main
java
test
java
within the src/main/java/ directory the package name for you productive java class source files should added. within the src/test/java/ the package name for the unit tests java class source files.
And you should NOT change the layout if you don't have really really good reasons to do so.
Furthermore redefining the defaults of Maven defaults (target, target/classes, target/test-classes etc.) is against the convention over configuration paradigm.
Be aware that you need to follow a naming convention for unit tests which means you unit tests should be named like the following:
<includes>
<include>**/*Test*.java</include>
<include>**/*Test.java</include>
<include>**/*TestCase.java</include>
</includes>
But in your case I assume that we are talking about integration tests which means you need to use the following naming convention
<includes>
<include>**/IT*.java</include>
<include>**/*IT.java</include>
<include>**/*ITCase.java</include>
</includes>
Apart from that you should now that unit tests in Maven will be executed by the maven-surefire-plugin whereas the integration tests will be executed by the maven-failsafe-plugin.
To get around the testng annotations not found errors I ended up moving the base class from src/main/java/package1/baseclass.java to src/main/test/package1/baseclass.java and the testng annotations errors resolved

Converting a Maven 1 project into Maven 2

I'm new to Maven, and have been running into some difficulty in a project. I am to convert a Maven 1 project into Maven 2.
I started with these files:
maven.xml -- contains custom build scripts
project.properties -- general build settings
project.xml -- Project Object Model (POM) definition
From my understanding, Maven 2 project I must move these files into these:
pom.xml -- POM definition
(and possibly) settings.xml -- local configuration
I have gone about this by using the command 'mvn one:convert'.
This seemed to take care of project.xml > pom.xml
I then added a to pom.xml to include project.properties (which seemed to work).
Am I right in assuming that all I have left is to transfer over the contents of maven.xml >> pom.xml ?
maven.xml starts with:
<project default="site_deploy"
xmlns:ant="jelly:ant"
xmlns:maven="jelly:maven"
xmlns:j="jelly:core"
xmlns:util="jelly:util">
<ant:property environment="env"/>
and contains contains goals such as:
<goal name="site_deploy">
<attainGoal name="clean"/>
<attainGoal name="clean:clean"/>
<ant:delete dir="${maven.src.dir}/core/target" />
<attainGoal name="core_deploy"/>
</goal>
<goal name="core">
<maven:maven
descriptor="core/project.xml"
goals="jar:install"/>
<ant:property name="m2Dir" value="${maven.repo.local}/../../.m2/repository/app/${application.version}"/>
<ant:property name="m1Path" value="${maven.repo.local}/${application.id}/jars/${application.id}-core-${application.version}.jar"/>
<ant:echo message="copying jar m1 to m2 (${m1Path}) to (${m2Dir})" />
<ant:mkdir dir="${m2Dir}"/>
<ant:copy todir="${m2Dir}" file="${m1Path}" />
</goal>
From my reading if not bound to any build phase, goals can be executed outside of the build lifecycle by direct invocation, the second way being to write plugins for the goals.
How would I identify if the goals have dependencies-- how would I go about writing a plug-in? I've been referring mostly to the maven guides on apache.org, but some of it is hard to follow.
Here is the pom file generated:
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>${application.id}</groupId>
<artifactId>${application.artifact}</artifactId>
<version>${application.version}</version>
<name>${application.name}</name>
<inceptionYear>2007</inceptionYear>
<organization>
<name>OrganizationName</name>
<url>http://organization.url</url>
</organization>
<scm>
<connection>scm:svn:connection</connection>
<url>http://svn.organization.local/svn/trunk/application_name</url>
</scm>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<artifactId>maven-changes-plugin</artifactId>
<configuration>
<xmlPath>${basedir}/xdocs/changes.xml</xmlPath>
</configuration>
</plugin>
</plugins>
</reporting>
</project>

Maven Assembly Plugin - install the created assembly

I have a project that simply consists of files. I want to package those files into a zip and store them in a maven repository. I have the assembly plugin configured to build the zip file and that part works just fine, but I cannot seem to figure out how to install the zip file?
Also, if I want to use this assembly in another artifact, how would I do that? I am intending on calling dependency:unpack, but I don't have an artifact in the repository to unpack.
How can I get a zip file to be in my repository so that I may re-use it in another artifact?
parent pom
<build>
<plugins>
<plugin>
<!--<groupId>org.apache.maven.plugins</groupId>-->
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
<configuration>
<filters>
<filter></filter>
</filters>
<descriptors>
<descriptor>../packaging.xml</descriptor>
</descriptors>
</configuration>
</plugin>
</plugins>
</build>
Child POM
<parent>
<groupId>com. ... .virtualHost</groupId>
<artifactId>pom</artifactId>
<version>0.0.1</version>
<relativePath>../pom.xml</relativePath>
</parent>
<name>Virtual Host - ***</name>
<groupId>com. ... .virtualHost</groupId>
<artifactId>***</artifactId>
<version>0.0.1</version>
<packaging>pom</packaging>
I filtered the name out. Is this POM correct? I just want to bundle files for a particular virtual host together.
Thanks,
Walter
I have the assembly plugin configured to build the zip file and that part works just fine, but I cannot seem to figure out how to install the zip file?
Well, the created assembly should get automatically attached to the project and then uploaded into the repository on an install and deploy goal. Can you show your pom?
Update: With your current configuration, I don't think that the assembly gets created as part of your build. You need to bind the single goal to a lifecycle phase, typically package:
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
<configuration>
<descriptors>
<descriptor>../packaging.xml</descriptor>
</descriptors>
</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>
And now it should get installed/deployed properly.
Also, if I want to use this assembly in another artifact, how would I do that? I am intending on calling dependency:unpack, but I don't have an artifact in the repository to unpack.
You can declare a dependency on an assembly (using the right classifier and type in your case) but since dependency are resolved through the repository, you'll need to solve the first step first. Then, declare something like this (where the classifier is the assembly's id):
<dependency>
<groupId>com. ... .virtualHost</groupId>
<artifactId>***</artifactId>
<version>0.0.1</version>
<classifier>...</classifier>
<type>zip</type>
</dependency>
I think assemblies are supposed to be automatically attached to the build, but if that doesn't work, the Maven Build Helper "attach-artifact" goal attaches a specified file to be installed in the repository. I've used this plugin for installing files created by an external process like Ant or NSIS.
I don't know wether this could be usefull for you, but as a JAR file is basically a ZIP file plus the META-INF information, you could create your project as a jar without sources and add the xip countents in src/main/resources without needing any plugin configuration.
If you want your content to be in a different location, you can always do something like:
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.myzip</groupId>
<artifactId>myzip-artifact-id</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<build>
<resources>
<resource>
<targetPath>.</targetPath>
<filtering>false</filtering>
<directory>${basedir}/zipcontent</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
</build>
</project>
I f you want your artifact to be installed and being accessible in a repository you will need to set it up for the deploy phase:
http://maven.apache.org/plugins/maven-deploy-plugin/usage.html

How to filter resource in Maven, replacing with a dependencies artifactId?

I'm trying to build a jar that has an xml file as a resource. I'd like to apply a filter to that xml to insert the name of a dependency into the xml. The filtering is working, because I was able to drop in ${project.build.finalName} and get it replaced. I found one hint that the property I'm looking for might be
${project.dependencies[0].artifactId}
but that doesn't seem to work. I'm looking to replace
<fileName>${project.dependencies[0].artifactId}</fileName>
with
<fileName>OtherLibrary</fileName>
Is that possible?
xml, which is in src/main/resources:
<somenode>
<fileName>${project.dependencies[0].artifactId}</fileName>
</somenode>
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<groupId>com.foo</groupId>
<artifactId>Thing</artifactId>
<version>1.0-SNAPSHOT</version>
<name>Thing</name>
<url>http://maven.apache.org</url>
<build>
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
</build>
<dependencies>
<dependency>
<groupId>com.pts</groupId>
<artifactId>OtherLibrary</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Damn, you're right, this property doesn't get replaced during the filtering of resources. That's weird and it sounds like a bug in the Maven Resources Plugin because this property is correctly interpolated during the process-resources phase as I'll demonstrate in the workaround I'm suggesting below (based on the maven-antrun-plugin and the replace task).
First, add the following to your POM:
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>process-resources</phase>
<configuration>
<tasks>
<echo>${project.dependencies[0].artifactId}</echo><!-- I'm a test -->
<replace file="${project.build.outputDirectory}/myxmlfile.xml"
token="###" value="${project.dependencies[0].artifactId}"/>
</tasks>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
Then, update your XML file into:
<somenode>
<fileName>###</fileName>
</somenode>
With these changes, running mvn process-resources would produce the following result:
$ cat target/classes/myxmlfile.xml
<somenode>
<fileName>OtherLibrary</fileName>
</somenode>
Which proves the property is interpolated (but not set during maven filtering of resources)1. And if you need to filter more than one file, the replace task can take a fileset. Adapt it to suit your needs.
1 Actually, it would be nice to create a new Jira for this bug in the Maven 2.x Resources Plugin. I've created MRESOURCES-118.
The indexed properties will only be available inside plugin configuration due to the way Maven interpolates the POM - so it is available to antrun's replace task, but not the filtering.
However, accessing dependencies by index is not very robust - it is susceptible to changes in the parent. You might instead use the following in pom.xml:
<properties>
<fileName>some-name</fileName>
</properties>
...
<dependency>
<groupId>your.group.id</groupId>
<artifactId>${fileName}</artifactId>
...
</dependency>
You can then continue to filter using the property name:
<somenode>
<fileName>${fileName}</fileName>
</somenode>

Maven : OSGI, bundles and multi-modules projects

I'm currently developing an OSGi based application (using Equinox) by trying to mavenize a web tutorial I've found on OSGi+Equinox. In this project, there are bundles depending on other bundles (quote-service depends on quote).
The compile phase does succeed, but the package phase does not. Maven complains the following :
[INFO] [bundle:bundle]
[ERROR] Error building bundle de.vogella.osgi:quote-service:bundle:0.0.1 : Unresolved references to [de.vogella.osgi.quote] by class(es) on the Bundle-Classpath[Jar:dot]: [de/vogella/osgi/quoteservice/Activator.class, de/vogella/osgi/quoteservice/QuoteService.class]
[ERROR] Error(s) found in bundle configuration
I do understand the problem, but do not see how to make it work.
This is the quote's pom :
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>osgi-first-app</artifactId>
<groupId>de.vogella.osgi</groupId>
<version>0.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>de.vogella.osgi</groupId>
<artifactId>quote</artifactId>
<packaging>bundle</packaging>
<name>Quote Bundle</name>
<version>0.0.1</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>1.4.3</version>
<extensions>true</extensions>
<configuration>
<instructions>
<_include>src/main/resources/META-INF/MANIFEST.MF</_include>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>
and the quote's bundle manifest :
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Quote Plug-in
Bundle-SymbolicName: de.vogella.osgi.quote
Bundle-Activator: de.vogella.osgi.quote.Activator
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Import-Package: org.osgi.framework;version="1.3.0"
Export-Package: de.vogella.osgi.quote
Then the quote-service's pom :
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>osgi-first-app</artifactId>
<groupId>de.vogella.osgi</groupId>
<version>0.0.1</version>
</parent>
<dependencies>
<dependency>
<groupId>de.vogella.osgi</groupId>
<artifactId>quote</artifactId>
<version>0.0.1</version>
<type>bundle</type>
</dependency>
</dependencies>
<modelVersion>4.0.0</modelVersion>
<groupId>de.vogella.osgi</groupId>
<artifactId>quote-service</artifactId>
<packaging>bundle</packaging>
<name>Quote Service Bundle</name>
<version>0.0.1</version>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>1.4.3</version>
<extensions>true</extensions>
<configuration>
<instructions>
<_include>src/main/resources/META-INF/MANIFEST.MF</_include>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>
And finally the quote-service's manifest :
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Quoteservice Plug-in
Bundle-SymbolicName: de.vogella.osgi.quoteservice
Bundle-Activator: de.vogella.osgi.quoteservice.Activator
Bundle-ActivationPolicy: lazy
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Import-Package: org.osgi.framework;version="1.3.0", \
de.vogella.osgi.quote;version="0.0.1"
Is there something wrong ? Thank you in advance !
The answer is quite simple : I removed the already defined manifest, and used bnd entries in the bundle plugin instructions. That works !
Tycho is designed to handle these types of problems.
I wrote a tool called auto-builder: http://code.google.com/p/auto-builder. It introspects PDE-based projects and generates Ant build files; it supports transitive closure over dependencies and all that jazz.
I posted a write-up: http://empty-set.net/?p=9. I wrote it because the Maven tools I played with, when integrated with PDE, didn’t “just work.” Basically, I wanted to do coding in PDE and have a Hudson-based CI without any fuss in between.
Generating Ant files is nice because it gives you all the benefits of a declarative build tool, but it leaves you with a procedural description of what it is doing.
I am looking for more PDE-based projects to test it on. There are a couple RFC-0112 Bundle repositories around, and I have some code for downloading dependencies. If anyone is interested, then I could integrate dependencies download with auto-builder.