Performing substitutions in Eclipse product configuration file with tycho - eclipse

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.

Related

p2-maven-plugin -- bundle conflicts with other existing bundle

I’m starting to use the p2-maven-plugin in order to integrate non-OSGi JARs into our project in a (hopefully) convenient manner.
I have an artifact which I want to OSGi-ify, called com.thirdparty.artifact. I’m current using p2-maven-plugin’s standard configuration, and I list my artifact in the pom.xml like so:
<artifact><id>com.thirdparty:artifact:1.2.3</id></artifact>
This artifact has a transitive dependency called com.thirdparty:library:2.5, which exports a package com.thirdparty.library which is in turn imported by com.thirdparty:artifact. When I run mvn p2:site, I get a P2 site which contains com.thirdparty:artifact:1.2.3 and com.thirdparty:library:2.5 -- all fine so far.
Now, things are turning messy. My existing target platform already contains an artifact called com.othervendor:library (different vendor, it’s there and I cannot change that), which also exports the very same package com.thirdparty.library (but an entirely different version).
At runtime, the OSGi/Eclipse black magic (which I’ll probably never fully understand) tries to resolve com.thirdparty:artifact’s dependency on the package com.thirdparty.library using the com.othervendor:library and not my provided com.thirdparty:library:2.5 -- and I’m obviously in trouble. Here’s a visualization of my situation:
Being absolutely no OSGi rocket scientist, my first idea was to inspect the MANIFEST.MF in com.thirdparty:artifact. Beside others, this shows the following:
Import-Package: com.thirdparty.library
So, this obviously just tells com.thirdparty:artifact to import this package from some bundle, and OSGi/Eclipse thinks “okay, com.othervendor:library is more adequate than com.thirdparty:library”.
There seem to be two methods of narrowing down the dependencies to actually use. However: I’m not sure (a) how to integrate them into my p2-maven-plugin workflow, and (b) I do not understand why p2-maven-plugin does not automatically require the concrete package version in the Import-Package directive (this information is after all already specified in the source pom.xml).
Probably I’m not seeing the forest for the trees here. So any general advice beside my questions above is very welcome!
[edit] Here’s my pom.xml (the concrete library which I’m about to OSGi-ify is Selenium):
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>com.example.p2dependencies</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<build>
<plugins>
<plugin>
<groupId>org.reficio</groupId>
<artifactId>p2-maven-plugin</artifactId>
<version>1.2.0</version>
<executions>
<execution>
<id>default-cli</id>
<configuration>
<artifacts>
<artifact><id>org.seleniumhq.selenium:selenium-java:3.4.0</id></artifact>
</artifacts>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
[edit2] Problem seems to be solved, it seems, the issue was an additional package which was only exported by com.othervendor:library.

Get eclipse plugin for JAR distribution

I want to use io.reactivex rxjava in Eclipse RCP application.
What is the best way to get it as eclipse plugin, including a source plugin?
Is there a project doing those convertions?
It is not included into the eclipse/orbit.
Or do i need to do it on my own?
Frank
If the original provider is not making an OSGI ready bundle for you (i.e. adding in the few extra bits to the MANIFEST.MF), you can make your own bundle with the Eclipse Bundle Recipes (EBR).
As of writing this (Oct 2015) Eclipse Orbit is currently moving to EBR for new bundles as they are packaged up. But you can do your own. Hopefully by time time some future person reads this, the EBR website will be a bit more complete https://www.eclipse.org/ebr/, but for now these slides and blog posts should get you started:
https://www.eclipsecon.org/na2015/sites/default/files/slides/Tasty%20Recipes%20for%20OSGi%20Bundles.pdf
http://wagenknecht.org/blog/archives/2014/02/eclipse-bundle-recipes.html
The basic idea is you need to connect it up to Maven with a pom.xml that looks a little like this:
<?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>
<artifactId>apache-commons</artifactId>
<version>1.0.0-SNAPSHOT</version>
</parent>
<artifactId>org.apache.commons.codec</artifactId>
<version>1.9.0-SNAPSHOT</version>
<packaging>eclipse-bundle-recipe</packaging>
<name>Apache Commons Codec</name>
<dependencies>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.9</version>
</dependency>
</dependencies>
</project>
This works along with the bnd file that looks a little like this:
package-version=${version;===;${Bundle-Version}}
Export-Package: \
*.internal*;x-internal:=true;version="${package-version}", \
*.impl*;x-internal:=true;version="${package-version}", \
*;version="${package-version}"
Import-Package: \
*
And there you go, with the above and a simple maven invocation, you have an OSGI bundle to use with your Eclipse RCP application.
Note that you will probably come across the question of what to name the bundle you are creating, Eclipse has some guidelines that may help: https://wiki.eclipse.org/Bundle_Naming

Plugin JARs are missing in an application built with Tycho

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.

Beginner Steps to Configure a Java Project to Build with Apache Maven

I've been given the task of migrating an existing project -- formerly built with Ant -- to use Apache Maven. I'm brand new to the entire concept, though I've spent the last several hours doing as much research as I can on the subject. Sadly, I'm having some proxy issues when it comes to installing things like m2e and Eclipse IAM, so everything must be done from the command prompt. As of right now, I do have maven installed properly; the trick now is to use it in my project rather than Ant. I've looked online and found a few tutorials, but they are all too vague for me considering my lack of experience with all of this. If anyone can break the steps down for me one-by-one in a detailed manner, that would be more than amazing. On a side note, I've been told to add the following to the local Maven Settings:
<settings>
<servers>
<server>
<id>local_tomcat</id>
<username>admin</username>
<password>tomcat</password>
</server>
<server>
<id>artifactory</id>
<username>user</username>
<password>password</password>
</server>
</servers>
<mirrors>
<mirror>
<id>artifactory</id>
<name>Artifactory</name>
<url>https://jenkins.web.jw.local/artifactory/repo1</url>
<mirrorOf>central</mirrorOf>
</mirror>
</mirrors>
<proxies>
<proxy>
<active>true</active>
<protocol>http</protocol>
<host>proxy.jw.local</host>
<port>80</port>
<username>user</username>
<password>password</password>
<nonProxyHosts>*.jw.local</nonProxyHosts>
</proxy>
</proxies>
</settings>
With the obvious username and password information filled in. I think I've managed that thus far by simply adding the necessary blocks into the settings.xml file under my ApacheMaven\conf directory. Other than that single step, I'm pretty much lost. Again, any help, especially that of a detailed tutorial in terms of command line instructions to build this project would be wonderful. Oh, and on another side-note, I am using Eclipse... Not sure if that would matter much.
EDIT: Considering Petr Kozelka's answer, I've attempted to make a pom.xml file for my project. Here's what I have so far...
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.company</groupId>
<artifactId>appName</artifactId>
<version>1.0.0</version>
<packaging>war</packaging>
<name>Application Name</name>
<description>Yadda Yadda</description>
<build>
<plugins>
</plugins>
</build>
<dependencies>
</dependencies>
<repositories>
</repositories>
</project>
Is this heading in the right direction? Also, do I need to construct the archetype.xml file myself, or will Maven do that through the command line somehow? If I need to do it myself, this is what I've come up with thus far:
<archetype xmlns="http://maven.apache.org/plugins/maven-archetype-plugin/archetype/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-archetype-plugin/archetype/1.0.0 http://maven.apache.org/xsd/archetype-1.0.0.xsd">
<id>lighthouse</id>
<sources>
<source>src/com/jeldwen/lighthouse/controller/AddTimeController.java</source>
<source>src/com/jeldwen/lighthouse/controller/BugController.java</source>
<source>src/com/jeldwen/lighthouse/controller/DeleteTimeController.java</source>
<source>src/com/jeldwen/lighthouse/controller/EnterTimeController.java</source>
<source>src/com/jeldwen/lighthouse/controller/ModifyTimeController.java</source>
<source>src/com/jeldwen/lighthouse/controller/PersonController.java</source>
<source>src/com/jeldwen/lighthouse/controller/ProjectController.java</source>
<source>src/com/jeldwen/lighthouse/controller/TimeController.java</source>
<source>src/com/jeldwen/lighthouse/model/Area.java</source>
<source>src/com/jeldwen/lighthouse/model/Bug.java</source>
<source>src/com/jeldwen/lighthouse/model/DBModel.java</source>
<source>src/com/jeldwen/lighthouse/model/DefaultModel.java</source>
<source>src/com/jeldwen/lighthouse/model/JWModel.java</source>
<source>src/com/jeldwen/lighthouse/model/JWTime.java</source>
<source>src/com/jeldwen/lighthouse/model/Person.java</source>
<source>src/com/jeldwen/lighthouse/model/Project.java</source>
<source>src/com/jeldwen/lighthouse/util/Lighthouse.java</source>
<source>src/com/jeldwen/lighthouse/util/LighthouseApplicationListener.java</source>
<source>src/com/jeldwen/lighthouse/util/LighthouseServlet.java</source>
<source>src/com/jeldwen/lighthouse/util/LighthouseSystemProperties.java</source>
<source>src/com/jeldwen/lighthouse/LighthouseApp.java</source>
</sources>
<testSources>
<!-- None -->
</testSources>
<allowPartial>true</allowPartial>
</archetype>
First of all: if you wish to customize settings.xml, do not touch the one in maven distro - instead, create a new file in $HOME/.m2/settings.xml where maven finds and uses it.
As the very first step, I recommend you to not use settings.xml at all.
Create a supersimple maven project, and try to compile it:
mvn clean install
Second step
Use very simple settings.xml:
you probably do not need proxy
servers part is needed only for publishing artifacts to a maven repository; that's not important at the beginning
here it is:
<?xml version="1.0" encoding="UTF-8"?>
<settings>
<mirrors>
<mirror>
<id>repos</id>
<mirrorOf>*</mirrorOf>
<name>internal mirror</name>
<url>https://jenkins.web.jw.local/artifactory/repo1</url>
</mirror>
</mirrors>
<!-- TODO: the proxy part here -->
</settings>
This assumes that you use inhouse maven repository, for instance Nexus or Artifactory.
Using maven repo makes only sense if your projects are not happy with deps available in the Maven Central Repository - otherwise, you can safely go without it. (let's neglect the performance effect of repoman for now)
Now, add some java sources, dependencies etc. - and watch how new depenencies get automatically downloaded to your local repository...
Third step
Learn how to add further repositories to your repository manager (group "public" on Nexus)...
The rest is probably subject of further research.

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?