maven-tiles
maven-tiles copied to clipboard
Tiles do not work with profiles
If a tile defines a profile the profile cannot be used in dependent projects. The profile is "visible" within the effective pom of the dependent project but cannot be activated.
I've tested it by using 2 things defined in the tile: a) a dependency (this works fine) b) a profile "test"
By building the project with "mvn .... -Ptest" I get the message "The requested profile ... test ... could not be activated because it does not exist.
Hi, thanks for the issue and sorry for the so late reply! I cannot find the time to play around maven-tiles and see if/how the code could be adapted to provide also profile merging, but I guess that it would be worthwhile to try it.
The TilesModelMerger should be responsible for merging profiles - https://github.com/maoo/maven-tiles/blob/master/tiles-maven-plugin/src/main/java/it/session/maven/plugin/TilesModelMerger.java
I will try to find some time to investigate.
I had the same problem. So I removed the profile from within the tile and added a profile in the pom where I include the tile, and put the tile inclusion within that profile. Then however the tiles plugin gets a NullPointerException during merge. My Tile only contained the maven-antrun-plugin with an "echo" and "copy" task.
Here is the stacktrace:
[ERROR] Internal error: java.lang.NullPointerException -> [Help 1]
org.apache.maven.InternalErrorException: Internal error: java.lang.NullPointerException
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:168)
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:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
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)
at org.codehaus.classworlds.Launcher.main(Launcher.java:47)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Caused by: java.lang.NullPointerException
at org.apache.maven.model.merge.ModelMerger.mergeConfigurationContainer_Configuration(ModelMerger.java:2651)
at org.apache.maven.model.merge.ModelMerger.mergeConfigurationContainer(ModelMerger.java:2627)
at org.apache.maven.model.merge.ModelMerger.mergePlugin(ModelMerger.java:2500)
at it.session.maven.plugin.TilesModelMerger.merge(TilesModelMerger.java:29)
at it.session.maven.plugin.TilesMavenLifecycleParticipant.mergeTile(TilesMavenLifecycleParticipant.java:129)
at it.session.maven.plugin.TilesMavenLifecycleParticipant.mergeTiles(TilesMavenLifecycleParticipant.java:177)
at it.session.maven.plugin.TilesMavenLifecycleParticipant.afterProjectsRead(TilesMavenLifecycleParticipant.java:168)
at org.apache.maven.DefaultMaven.doExecute(DefaultMaven.java:274)
at org.apache.maven.DefaultMaven.execute(DefaultMaven.java:156)
... 17 more
This is what my tile looks like:
<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>Build</artifactId>
<groupId>se.natusoft.osgi.aps</groupId>
<version>0.9.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>DeployBundleTile</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<configuration>
<target>
<echo message="Deploying ${project.build.finalName} to ${server.deploy.dir}"/>
<copy file="target/${project.build.finalName}.jar" todir="${server.deploy.dir}" failonerror="false"/>
</target>
</configuration>
<executions>
<execution>
<id>server-deploy</id>
<goals>
<goal>run</goal>
</goals>
<phase>install</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Hi Tom, thanks for the feedback; I'm trying to reproduce your NPE, but I can't. Here's what I did:
- Created a tile with your contents (but no parent):
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>se.natusoft.osgi.aps</groupId>
<version>0.9.0</version>
<artifactId>DeployBundleTile</artifactId>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
<configuration>
<target>
<echo message="Deploying ${project.build.finalName} to ${server.deploy.dir}"/>
<copy file="target/${project.build.finalName}.jar" todir="${server.deploy.dir}" failonerror="false"/>
</target>
</configuration>
<executions>
<execution>
<id>server-deploy</id>
<goals>
<goal>run</goal>
</goals>
<phase>install</phase>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
- mvn install
- Created - in a different folder - the tile aggregator, defined as follows:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>it.session.maven</groupId>
<artifactId>issue7</artifactId>
<version>1.0-SNAPSHOT</version>
<profiles>
<profile>
<id>staging</id>
<properties>
<tile.firstone>se.natusoft.osgi.aps:DeployBundleTile:0.9.0</tile.firstone>
</properties>
</profile>
</profiles>
<build>
<plugins>
<plugin>
<groupId>it.session.maven.plugins</groupId>
<artifactId>tiles-maven-plugin</artifactId>
<version>0.8-beta-6</version>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
</project>
- mvn clean install ## ant-run is not executed
- mvn clean install -Pstaging ## ant-run gets executed
Thanks, Maurizio
Hello Maurizio,
Thanks for a very quick reply!
It could be my parent that causes the problem. The tile shouldn't really have a parent, it hasn't occured to me until now that it does. I am going to do some more tests myself, but right now I have to run to a meetup where there will be beer so that of course have higher priority :-).
Hey Tom, I share your prioritization: beers come first :-) Keep us posted!
Hello again Maurizio,
I think I've come closer to the problem, and why your test worked. The problem occurs when I include more than one tile. Either one or the other tile I have works fine by itself, but when I do both at the same time I get the NPE.
My inclusion looks like this:
<tile.doc>${project.groupId}:DocTile:${project.version}</tile.doc>
<tile.deploy>${project.groupId}:DeployBundleTile:${project.version}</tile.deploy>
I moved the second one up from the profile just for testing. If I comment out one or the other it works. The <tile.doc> one looks very much like the <tile.deploy> one, just another plugin being defined. I wont include the <tile.doc> one since it is much larger and contains things you don't have so it will not be useful for you. It is not the content of the tile that is the problem. Either of them work fine when alone. It is when both are enabled the NPE occurs.
In your example you included more than one tile in a pom. The only difference I see between your examples where you also define plugins is that your don't have any
Hello again Maurizio,
The simple test works fine. I started out with this simple "user" pom:
<?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">
<modelVersion>4.0.0</modelVersion>
<groupId>TilesTest</groupId>
<artifactId>TilesTest</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>TileOne</module>
<module>TileTwo</module>
</modules>
<properties>
<tile.1>TileTest:TileOne:1.0</tile.1>
<tile.2>TileTest:TileTwo:1.0</tile.2>
</properties>
<build>
<plugins>
<plugin>
<groupId>it.session.maven.plugins</groupId>
<artifactId>tiles-maven-plugin</artifactId>
<version>0.8-beta-6</version>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
</project>
and my tiles and it failed. That means that there is something within the tiles and not the pom that gets them included that causes the problem. I have to dig deeper, but it is going to take time. I'll get back to you if I find something useful.
The tiles plugin is a great idea and really solves a problem. Thank you for doing it! I'm a big fan of maven, but it is not 100% perfect. The tiles plugin take it one step further however. You should try to get the maven guys to take it in as a standard part of maven.
Tom, thank you so much for your technical investigations and your kind words about Maven Tiles; I also feel that the concept of Tile (or Mixin, not really picky on names) is crucial to provide a next-generation build tool and I am glad to find people thinking alike.
To be sincere, I'm not sure yet whether the Tiles Maven Plugin will (ever) achieve the stability and reliability to become a widely used plugin, as I still believe that this feature should be part of Maven core; nevertheless, for now the Tiles Maven Plugin code is extremely simple and easy to test... let's see where this will bring us!
Jeehaa!, I found it! :-)
I cloned your code and added some debug printouts:
public class TilesModelMerger extends ModelMerger {
public void merge(Model target, Model source, boolean sourceDominant, Map<?, ?> hints) {
Map<Object, Object> context = new HashMap<Object, Object>();
if (hints != null) {
context.putAll(hints);
}
super.merge(target, source, sourceDominant, hints);
if (source.getBuild() != null) {
super.merge(target, source, sourceDominant, context);
for (Plugin sourcePlugin : source.getBuild().getPlugins()) {
System.out.println("target:" + target.getName() + "(" + target.getGroupId() + ":" + target.getId() + ")");
for (String key : target.getBuild().getPluginsAsMap().keySet()) {
System.out.println("Key: [" + key + "]");
}
Plugin targetPlugin = target.getBuild().getPluginsAsMap().get(sourcePlugin.getKey());
System.out.println("targetPlugin=[" + targetPlugin + ", sourcePlugin.getKey()=[" + sourcePlugin.getKey() + "]");
super.mergePlugin(targetPlugin, sourcePlugin, sourceDominant, context);
}
}
}
}
This clearly showed that "maven-antrun-plugin" was not among the plugins available for the target. This made the targetPlugin null in:
Plugin targetPlugin = target.getBuild().getPluginsAsMap().get(sourcePlugin.getKey());
But when the tile using the maven-antrun-plugin is the only tile included it is among the target plugins! Why this is so is a completely different question :-). When there are more than one tile included it is always the second that fails. Could it possible be the first merge that causes this ?
I however found a workaround to this, I put this in my parent pom:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.6</version>
</plugin>
That forced it to be available and then it worked fine.
Tom, that's awesome. Unfortunately my time for applying your changes is very limited and I think that it needs some testing before committing. How would you feel to contribute to maven-tiles? If you ask, I can give you commit rights immediately. Thanks again!
Sorry, you missunderstood me. There are no changes to fix. All I added were some debug printouts just so that I could easier determine the problem. I had a suspicion from the stack trace what to look at. I just tried to explain how I found the problem, but I have tendencies to provide too much information sometimes :-).
As long as I define the plugins I use in tiles somewhere outside the tiles in their simplest form (group, artifact, version) then the NPE problem goes away.
So there is nothing you need to do :-)
That's a very good news!
I see from the stacktrace that the NPE comes from tiles code: at it.session.maven.plugin.TilesModelMerger.merge(TilesModelMerger.java:29)
I would like to see if there's a way to prevent it. Thanks!
And even the printouts could be contributed as log.debug()! Might help understanding what's going on