Plugin JARs are missing in an application built with Tycho - plugins

I am building an Eclipse application with Maven Tycho. I managed to create the pom files for building the plugins and features. I ran install on them and got Build successful. I have also cretaed the pom for the application (product) and set the Packaging to "eclipse-application". The application is feature-based. I ran install and got the Build successful. I got the generated folder for the application, containing the folders "plugins" and "features".
The problem is that not all the jar files, for all the plugins, can be found in the plugins folder. I can find the jar files for the plugins that are listed in the features. But the jar files for the plugins listed in the Dependencies tab of other plugins are not generated. In other words, only the plugins referenced in the features are generated as jar files, while the jar files for the ones referenced in the plugins are not generated.
Obviously, I cannot run the application without them. What am I doing wrong? How can I get all the required jar files generated?
Thank you!

Firstly, don't use eclipse-application. It has been deprecated, and, being someone that has tried to make it work with his own projects, I can tell you that it's a bad idea as it has a lot of problems. Instead, use eclipse-repository.
Secondly, the only .jar files that will show up in your products plugins directory will be ones that have compiled successfully, and are also in the dependencies section of your .product file, and not your manifest.mf.
I suspect that your problem is related to the second point, but I've seen eclipse-application do so many odd things that it alone might resolve your issue.

The first answer is on the right track... Use eclipse-repository.
To have Tycho generate a repository, you are probably using the tycho-p2-repository-plugin ... And if you're using that plugin, then you may want to add this little element to the configuration section.
<includeAllDependencies>true</includeAllDependencies>
Here's a larger sample of my pom.xml that's in my p2repository plugin.
<?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>
<parent>
<groupId>my.domain.product</groupId>
<artifactId>parent</artifactId>
<version>1.1.8-SNAPSHOT</version>
<relativePath>../my.domain.product.parent</relativePath>
</parent>
<artifactId>my.domain.product.p2repository</artifactId>
<packaging>eclipse-repository</packaging>
<name>My Product - P2 Repository</name>
<build>
<plugins>
<plugin>
<groupId>${tycho-groupid}</groupId>
<artifactId>tycho-p2-repository-plugin</artifactId>
<version>${tycho-version}</version>
<configuration>
<includeAllDependencies>true</includeAllDependencies>
<createArtifactRepository>true</createArtifactRepository>
<compress>true</compress>
</configuration>
</plugin>
</plugins>
Hope this helps.

Related

How to do a modular project architecture with Maven in Eclipse?

First of all im a little newbie in Maven+Eclipse world, so please excuse me if im not explaining myself good.
Im trying to implement Maven to existing Java old projects, the architecture im trying to achive is something like this (i put an image to explain myself a little better):
The project Utils have the most of the libs, that genericlly will be used for the other projects, and some classes that will be useful for the others (like date comparison method and mathematic method etc...), this project is working well with mvn install, generating the respective .war file.
The questions are:
The N Web Modules projects must have the project Utils as a
depedency and the most of dependencies too. I
don't know how to achive this in the pom.xml of N Web Modules
projects.
I don't know if it is posible in
Eclipse+Maven: Try to do some Parent Web Project that
implements the other projects and in one single mvn install the
parent project build and install the rest of the childs
(including Utils and N Web Modules).
I hope you can orientate and help me with this.
I think you are looking for Multi-Module projects
http://books.sonatype.com/mvnex-book/reference/multimodule.html
You can put various subprojects in one larger project and build them all at once. Furthermore, modules can depend on other modules (as long as this is not circular) and they are build in the correct order.
The project Utils have the most of the libs, that genericlly will be
used for the other projects, and some classes that will be useful for
the others (like date comparison method and mathematic method etc...),
this project is working well with mvn install, generating the
respective .war file.
One advise, you should extract classes used by other projects in a maven project with a JAR packaging and not leave them in a WAR packaging.
In Maven, generally, dependencies are provided as JAR.
It may also be provided as WAR by configuring the maven-war-plugin with some specific properties such as attachClasses but it looks like a trick and it also may create side effects.
Here are some information on how to do it.
But the documentation doesn't advise this way :
If you need to re-use this JAR/WAR in another project, the recommended
approach is to move the classes to a separate module that builds a
JAR, and then declare a dependency on that JAR from your webapp as
well as from any other projects that need it.
About your two questions.
The N Web Modules projects must have the project Utils as a dependency
and the most of dependencies too. I don't know how to achive this in
the pom.xml of N Web Modules projects.
Just include it as a dependency in the dependencies element of the consumer project :
<?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>mygroup</groupId>
<artifactId>project1-consumer</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
...
<dependencies>
<dependency>
<groupId>mygroup</groupId>
<artifactId>util</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
...
</dependencies>
</project>
I don't know if it is posible in Eclipse+Maven: Try to do some Parent
Web Project that implements the other projects and in one single mvn
install the parent project build and install the rest of the childs
(including Utils and N Web Modules).
What you are looking for is designing a multi-module project.
It relies on a aggregator pom that declares each module.
Note that this module has to be specified with a pom packaging as it doesn't produce a consumable artifact.
You could define something like that :
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>mygroup</groupId>
<artifactId>myaggregatorpom</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>util</module>
<module>project1-consumer</module>
<module>project2-consumer</module>
</modules>
</project>

Performing substitutions in Eclipse product configuration file with tycho

I have a Eclipse RCP product which I build with Tycho. After some smaller issues, this is working pretty fine and I have both CI and releases as wanted.
The product in question is provided both as an installable stand-alone RCP application and as an update site so the functionality can be installed in a vanilla Eclipse installation. This works fine as well.
The product have a main feature - which is used on the update site - and I would very much like the feature and the product to have the same version number. As it is today, this version number is mentioned is many places and I would really like to reduce this to just one. I currently have the version number in
the feature.xml of the main feature
the pom.xml of the same feature
the .product file for the product configuration file
the pom.xml of the project with the .product file
the categories.xml file of the update site
the about.mappings file
I have tried to use maven resource filters and that works for the POM files and about.mappings, but not for the rest. This is my current pom.xml for the main feature:
<?xml version="1.0" encoding="UTF-8"?>
<project ...>
<modelVersion>4.0.0</modelVersion>
<artifactId>...main.feature</artifactId>
<version>${product.version}-SNAPSHOT</version>
<packaging>eclipse-feature</packaging>
<parent>
<groupId>...</groupId>
<artifactId>...parent</artifactId>
<version>1.0.0-SNAPSHOT</version>
<relativePath>../...parent</relativePath>
</parent>
<build>
<!-- Substitutions: product.version -->
<resources>
<resource>
<directory>.</directory>
<includes>
<include>feature.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
When running this configuration, I get the following exception from Tycho (or an exception that looks very similar to it):
[ERROR] Internal error: java.lang.IllegalArgumentException -> [Help 1]
org.apache.maven.InternalErrorException: Internal error: java.lang.IllegalArgumentException
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)
Caused by: java.lang.IllegalArgumentException
at org.eclipse.equinox.internal.p2.metadata.VersionParser.parse(VersionParser.java:93)
at org.eclipse.equinox.p2.metadata.Version.create(Version.java:79)
at org.eclipse.tycho.p2.impl.publisher.FeatureDependenciesAction.getVersion(FeatureDependenciesAction.java:126)
at org.eclipse.tycho.p2.impl.publisher.AbstractDependenciesAction.perform(AbstractDependenciesAction.java:79)
... 11 more
(I have cut some lines...)
Basically, the embedded maven process seems to not perform the resource filtering at all for this type of packaging. Or??
I have tried many different things, but I cannot get it to work. My best guess is that I have to configure the lifecycle, but how...
Can anybody help me with this?
this is a known bug:
https://bugs.eclipse.org/bugs/show_bug.cgi?id=362252
You don't need to specify versions explicitly in the categories.xml. Just specify 0.0.0 as version, and Tycho will replace it by the actual version of the included feature.

m2eclipse and/or wtp not packaging a dependency correctly?

Eclipse Indigo SR 1, wtp 3.3.0, m2eclipse 1.0.100.
When publishing a project to WTP, I'm getting strange behavior with one of the dependencies; instead of putting the jar in the WEB-INF/lib folder, it's creating a folder named for the expected jar, and then putting the source tree (apparently) from that project under that folder. I can't see anything in the dependency's pom.xml or this project's pom.xml that could be causing this.
Other dependencies are being brought over just fine, as jars.
My test project's pom.xml:
<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">
<modelVersion>4.0.0</modelVersion>
<groupId>test</groupId>
<artifactId>dwhwtptest</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>dwhwtptest Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>org.onebusaway</groupId>
<artifactId>onebusaway-nyc-transit-data</artifactId>
<version>2.0.3-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<finalName>dwhwtptest</finalName>
</build>
</project>
Here's what ends up being published at workspace/.metadata/.plugins/org.eclipse.wst.server.core/tmp0/wtpwebapps:
$ find dwhwtptest/
dwhwtptest/
dwhwtptest//index.jsp
dwhwtptest//META-INF
dwhwtptest//META-INF/MANIFEST.MF
dwhwtptest//META-INF/maven
dwhwtptest//META-INF/maven/test
dwhwtptest//META-INF/maven/test/dwhwtptest
dwhwtptest//META-INF/maven/test/dwhwtptest/pom.properties
dwhwtptest//META-INF/maven/test/dwhwtptest/pom.xml
dwhwtptest//WEB-INF
dwhwtptest//WEB-INF/lib
dwhwtptest//WEB-INF/lib/onebusaway-nyc-transit-data-2.0.3-SNAPSHOT.jar
dwhwtptest//WEB-INF/lib/onebusaway-nyc-transit-data-2.0.3-SNAPSHOT.jar/META-INF
dwhwtptest//WEB-INF/lib/onebusaway-nyc-transit-data-2.0.3-SNAPSHOT.jar/META-INF/MANIFEST.MF
dwhwtptest//WEB-INF/lib/onebusaway-nyc-transit-data-2.0.3-SNAPSHOT.jar/org
dwhwtptest//WEB-INF/lib/onebusaway-nyc-transit-data-2.0.3-SNAPSHOT.jar/org/onebusaway
dwhwtptest//WEB-INF/lib/onebusaway-nyc-transit-data-2.0.3-SNAPSHOT.jar/org/onebusaway/nyc
dwhwtptest//WEB-INF/lib/onebusaway-nyc-transit-data-2.0.3-SNAPSHOT.jar/org/onebusaway/nyc/transit_data
dwhwtptest//WEB-INF/lib/onebusaway-nyc-transit-data-2.0.3-SNAPSHOT.jar/org/onebusaway/nyc/transit_data/model
dwhwtptest//WEB-INF/lib/onebusaway-nyc-transit-data-2.0.3-SNAPSHOT.jar/org/onebusaway/nyc/transit_data/model/NycQueuedInferredLocationBean.java
dwhwtptest//WEB-INF/lib/onebusaway-nyc-transit-data-2.0.3-SNAPSHOT.jar/org/onebusaway/nyc/transit_data/model/NycVehicleManagementStatusBean.java
dwhwtptest//WEB-INF/lib/onebusaway-nyc-transit-data-2.0.3-SNAPSHOT.jar/org/onebusaway/nyc/transit_data/services
dwhwtptest//WEB-INF/lib/onebusaway-nyc-transit-data-2.0.3-SNAPSHOT.jar/org/onebusaway/nyc/transit_data/services/ConfigurationService.java
dwhwtptest//WEB-INF/lib/onebusaway-nyc-transit-data-2.0.3-SNAPSHOT.jar/org/onebusaway/nyc/transit_data/services/VehicleTrackingManagementService.java
dwhwtptest//WEB-INF/web.xml
And here's the pom.xml for the dependency, the onebusaway-nyc-transit-data module:
<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>
<parent>
<artifactId>onebusaway-nyc</artifactId>
<groupId>org.onebusaway</groupId>
<version>2.0.3-SNAPSHOT</version>
</parent>
<groupId>org.onebusaway</groupId>
<artifactId>onebusaway-nyc-transit-data</artifactId>
<packaging>jar</packaging>
<name>onebusaway-nyc-transit-data</name>
<description>Common interfaces and classes for exchanging transit data between UI front-end and transit back-end data sources.</description>
<build>
<finalName>onebusaway-nyc-transit-data</finalName>
</build>
</project>
Suggestions? Anything else I can investigate to try to figure out what's going on here?
A colleague of mine provided me an approach that fixed the issue, but it requires few manual steps.
remove the project from your eclipse
go to your maven root folder with a terminal and kill all the eclipse stuff using this command (you will have to do this twice):
$> find . -iname ".settings" -exec rm -rf '{}' \; ; find . -iname ".project" -exec rm -rf '{}' \; ; find . -iname ".classpath" -exec rm -rf '{}'
on your maven root, execute this command:
$> mvn -Dwtpversion=2.0 eclipse:eclipse
import your project back in eclipse: everything will now work and eclipse will be publishing jars containing code :)
HTH, Bruno (credits to Theodore!)
I suggest trying out the m2e-wtp plugin in addition to your currently installed m2e plugin (which doesn't contain support for WTP based projects) This plugin is available in the Eclipse Marketplace via the embedded Marketplace client or on the web (http://marketplace.eclipse.org/content/maven-integration-eclipse-wtp). It provides a tighter Maven integration with WTP and should improve the overall Maven with WTP experience.
If things still don't work go delete the publish folder. It will look something like:
<Path To Your IDE>\.metadata\.plugins\org.eclipse.wst.server.core\tmp0
First make sure you REMOVE the project under Tomcat or whatever other server you are using from withing the IDE. Then close the ID or you cannot delete the folder.
Once you do this, you can run your maven clean/build/install command and deploy your project.
If this does not work, this problem isn't related to the IDE or the Application Server.

Maven and Eclipse code organization

I'm new to Maven, and after having read the docs on the maven site and Sonatype's online Maven book, I'm still not clear on how to best organize things.
I have two apps, A and B which share code from mylib. Different developers work on apps A and app B, they are released independently. Before we started with maven, in Eclipse, I'd have a workspace with apps A and B and mylib. The classpath for app A contained mylib. If I made a change in mylib, pressing run within Eclipse, contained my latest changes.
In Maven, I can create a parent pom.xml, which references app A and mylib. But this makes mylib a subdirectory of app A. How can I keep one instance of mylib and not link the building of apps A and B?
We use SVN for our SCM
Thanks
You have multiple options, however, potentially the simplest approach would be to separate out mylib into its own Maven project with its own life-cycle. The benefit of this approach is that you can support having multiple versions of mylib and your apps A and B can reference different versions of mylib as needed. If mylib and appA are open in Eclipse (and mylib references the version of mylib you have open), you can build the application in the same manner as you did prior to using Maven.
This approach does not mandate any dependencies between the directory structures of the applications, so you could go with something similar to the following:
/myapps/mylib
/myapps/appA
/myapps/appB
The downside to this approach is that maven will not automatically build both appA and mylib (or appB and mylib) as they are treated as separate applications. However, this may not be much of an issue if your applications are using pre-defined and built versions of mylib (that have been uploaded to your local maven repository using "mvn install").
Here is an example of the POMs for these projects:
mylib:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>myLib</artifactId>
<versioning>0.0.1</versioning>
<packaging>jar</packaging>
<name>mylib</name>
...
</project>
appA:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>appA</artifactId>
<packaging>jar</packaging>
<name>appA</name>
...
<dependencies>
<groupId>com.text</groupId>
<artifactId>mylib</artifactId</artifactId>
<version>0.0.1</version>
</dependencies>
...
</project>
appB:
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.test</groupId>
<artifactId>appB</artifactId>
<packaging>jar</packaging>
<name>appB</name>
...
<dependencies>
<groupId>com.text</groupId>
<artifactId>mylib</artifactId</artifactId>
<version>0.0.1</version>
</dependencies>
...
</project>
If you still want the convenience of a parent POM (one mvn package comment), then you could create a master pom in the /myapps folder similar to the following:
<project>
<groupId>com.test</groupId>
<version>0.0.1</version>
<artifactId>myapps</artifactId>
<packaging>pom</packaging>
<name>myapps</name>
<modules>
<module>shared</modules>
<module>appA</modules>
<module>appB</modules>
</modules>
</project>
This POM will automatically build myapp, appA and appB. If desired you could also create an appA and appB specific POM (pom-appA.xml). This is not the cleanest approach from a Maven perspective, but it will function. The only issue you would run into is if the version of mylib is not the version on which appA or appB is dependent. In that case your appA or appB code would be compiling against the version in your maven repository (if that version exists).
There are many other options you can use as well and I have seen plenty of discussions on Blogs and Wikis as to which is the best for various scenarios. However, it usually comes down to what works best for you and your organization. As long as it works and you are not going off building a custom, non-portable maven solution, then you are probably doing ok.
Hopefully this gives you some thoughts that you can use.

Porting a tomcat web project from eclipse ganymede to intellij 8.1

I have a standard (I think) web project developed with the eclipse IDE. I wish to port it to Intellij idea 8.1 - I think that, among other things, it has better taglib support.
My project structure is as follows:
Project Folder
./src [java source files etc.]
./conf [configuration files - log4j, spring beans...]
./buid [ant files]
./WebContent
./WebContent/images [image files]
./WebContent/META-INF
./WebContent/META-INF/context.xml
./WebContent/pages [.jsp+.html files]
./WebContent/scripts [.js files]
./WebContent/skins [.css files]
./WebContent/WEB-INF
./WebContent/WEB-INF/classes [.class files]
./WebContent/WEB-INF/lib [.jar files]
./WebContent/WEB-INF/tags [.tag files]
./WebContent/WEB-INF/web.xml
I can't seem to get this project configured with my local tomcat server (version: apache-tomcat-6.0.18).
I think that a good answer would be a standard, step by step, cookbook answer as to how to port (and perhaps how to correctly define a tomcat web application within intellij idea).
Thanks all!
I think the first step would be to create a stand-alone build file which will produce a WAR. Do this before attempting to import the project into InteliJ.
I would use Maven. Creating a maven POM file to create a WAR is almost trivial and you can easily override the the default locations for your src, conf, and web content to match you existing src directory. Then test the build by deploying your newly Maven created WAR to Tomcat. I wouldn't think this first task would take more than a half day (at most a full day).
IntelliJ has a built in utility to import Maven projects. Then you should be off and running....
Regardless of the IDE you finally settle on, your project will be much better off in the long run for the Maven migration.
You initial Maven POM file will look something like this...
<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>com.yourcompany.yourapp</groupId>
<artifactId>yourapp</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>Your project name here</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
*** other dependencies here ***
</dependency>
</dependencies>
<build>
<sourceDirectory>src</sourceDirectory>
<resources>
<resource>
<directory>conf</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.0</version>
<configuration>
<webResources>
<resource>
<!-- this is relative to the pom.xml directory -->
<directory>WebContent</directory>
</resource>
</webResources>
</configuration>
</plugin>
</plugins>
</build>
</project>
*** This is an example POM only... It's just meant to get you started and may not work "as is".
Start off by creating an empty web application for tomcat, within IntelliJ - and make sure that it deploys correctly
This will produce a directory structure that you should then be able to copy your source files/web assets into.
The thing that you'll probably need to handle differently is the lib files - don't store these directly in the WEB-INF directory, as keeping them in a separate 'library' area, and allowing the IDE to include them in the WAR at build time is generally a better approach, as it promotes re-use across projects.
The key thing to aim for is to not try to set your project up to completely mirror a tomcat application, as the build process will pull together the various parts for you. It all breaks down into 3 sections...
Static assets - images, config files and jsp files (Ok, I know JSP files are kinda dynamic)
Java classes - source code that you write yourself (The IDE will compile these and place them in the appropriate location)
Java Libraries - third party code that you compile against (Again the IDE will place these in the appropriate location)
There are a few bits of configuration, within the project file, that you'll need to tweak to suit your needs, but it's generally straightforward.
By default, log4j will look for it's configuration file (either log4j.xml or log4j.properties) from the classpath of your application. So this means you should place it in WEB-INF\classes, or you can specify a different location with the environment variable log4j.configuration. See the log4j manual.
What IDE you use should have no impact on the structure of your application when it gets deployed to your servlet container. It sounds like maybe you were relying on Eclipse to package the files in a specific way - this is probably a bad practice. Are you using an actual build script?