Using annotations from a library which is not a bundle in a Tycho build - maven

I'm building an Eclipse plugin using Tycho and am making use of Declarative Services for my OSGi services. Eclipse has a nice Editor for DS files, but it still is a manual process, which means it's slow and error-prone.
In non-Tycho OSGi projects I can use the maven-scr-plugin to generate these annotations. The catch with Tycho is that I can't add a reference to the org.apache.felix.annotations jar since it's
not present in a p2 repository
not a bundle
These annotations are defined with a RetentionPolicy = CLASS, so they don't have to be in a bundle.
I know about dependency on pom-first artifacts, but it's not going to work for me since the annotations jar is not a bundle. Ideally I could just configure Tycho/Eclipse to look for an extra jar just at compile time.
How can I get a compile-time only jar considered by Tycho and Eclipse?
Update: I've tried to use the extraClasspathElements option of the tycho-compiler-plugin. That does allow me to invoke the maven-scr-plugin (see the current pom.xml). However, it seems that the scr plugin can't access the classes, as the build fails with
[ERROR] Failed to execute goal org.apache.felix:maven-scr-plugin:1.13.0:scr (generate-scr-descriptor) on project org.apache.sling.ide.eclipse-core: /mnt/md/robert/git/sling-ide-tools/eclipse-core/src/org/apache/sling/ide/eclipse/core/ServerUtil.java : Unable to load compiled class: org.apache.sling.ide.eclipse.core.ServerUtil
You can also see the full build log

Since you are using Tycho/Eclipse, you probably want to use "org.eclipse.equinox.ds" rather than "org.apache.felix.annotations". If I understand correctly, org.eclipse.equinox.ds is a bundle. The Tycho FAQ mentions this as well:
http://wiki.eclipse.org/Tycho/FAQ#How_to_add_a_undeclared_dependency.3F__.28e.g..2C_OSGi_declarative_service.29
EDIT:
http://eclipse.org/tycho/sitedocs/tycho-compiler-plugin/compile-mojo.html#extraClasspathElements
EDIT2: A lot has changed. I'll be updating my answer when time permits. Check the comment threads in the meantime =)

I think the best you can do is to separate your building in two steps.
One for building the felix (scr/bnd) based bundles. the result will be on a local maven repository and all will be already bundles with the manifests and component xmls.
As the annotation is processed only at building time you won't have any problem with the following step.
The second step is to build the tycho based artifacts(bundles,features,rcp,p2,etc) that will consume the bundles in the first build.

Related

What is the recommended usage pattern for karaf-maven-plugin?

I have a bunch of java classes and a bundle activator class that I need to deploy to karaf.
I see that the karat-maven-plugin has kar packaging and karaf-assembly.
Also it generates features.xml
I can generate features.xml directly and it generates lines with wrap: for some of my dependent non-osgi jars.
But when I run karat-assembly, I run into the issue of the assembly goal not realizing that these jars are not osgi and end up with errors.
What it the recommended way to get a custom karaf with my application installed ?
Does the karat-assembly packaging need to have a features.xml generated and provided beforehand ? Or is it supposed to do the feature set generation by itself ? If it is the latter, then how do I get around the problem of the karat-assembly not recognizing non-osgi jars ?
I have spent a LOT of time with google and am stumped.
This is my procedure for creating a custom karaf distribution. It may not be "best practice" but it works for me. Maybe you can customize for your needs.
After developing my Camel routes and testing I generate my feature file based on a feature template found in /src/main/feature/feature.xml. The karaf-maven-plugin will generate the feature will in the feature folder inside /target.
I do a clean deploy to our maven artifactory.
I have a custom Karaf project do a clean install on that project. The project has dependencies to the initial project and I add all the features as boot level feature.
Once build I unzip the distribution and run the Karaf app. If everything looks ok its ready to be shipped.

Reference a eclipse plugin from a regular project

this is a more conceptual question:
I want to create an application which uses the WALA framework, which itself is packaged as a eclipse plugin, built with maven-tycho. When I try to add this as an dependency no transitive dependency gets resolved, because they are covered by the tycho build.
This is the pom of the WALA project I need at least https://github.com/wala/WALA/blob/master/com.ibm.wala.core/pom.xml
Should my application be a OSGI Bundle itself or can I create a regular jar with it without having much trouble? Which approach is more practical?
If I have seen it correctly, wala.core has only two dependencies wala.util and wala.shrike (util has none, shrike depends on util). So you might as well simply include all three dependencies in your project.
On the long haul, however, you might should indeed consider creating an osgi application instead.

Update dependencies while in hosted mode in GWT

I have a GWT webapp split into two Maven projects where one is a dependency to the other. Each time I change something in the dependency and I'm running webapp in hosted mode I have to rebuild the subproject and restart hosted mode for changes to apply. It takes a lot of time so I'd like to ask you if there is any way to make GWT using "live" version of the dependency?
There are 2 cases:
for server-side code, assuming you use the DevMode's embedded server, rebuilding the app and then refreshing the server should be enough
for client-side code, AFAICT, you have to use the source and output directories of the dependency module rather than the JAR containing them (GWT will load the source from the classpath, but apparently it'll only see the modified sources if it comes from a folder rather than a JAR; at least that's what I found in my tests). This goes against The Maven Way™ but the only solution so far is to use a special profile that will import the sources of the dependency project as sources of the project you're running. You can see examples of that in my archetypes.
There's actually a bug opened for the gwt-maven-plugin, MGWT-332, to do that automatically when running a reactor build. I also mused about what's really needed, for the forthcoming official gwt-maven-plugin (rewritten from scratch, independent from the CodeHaus Mojo plugin).
If your dependency does not come from a reactor build, then you're out on your own: you chose to make it totally distinct, so that's how it'll behave: you'll have to release it (even a snapshot) each time you make a change to it, and use the new version in your app (which means re-launching the DevMode).
This can be circumvented by running DevMode on your own, without the help of the gwt-maven-plugin. You're left on your own managing the classpath though (using the Google Plugin for Eclipse, I suppose you could simply edit the launch configuration to add the source folders of your dependency project to the classpath, before the classpath provided by Maven, that would reference the JAR).
Remove the dependent other application jar file from the primary application lib folder under webapp.
Eclipse should then resolve the dependency using the other project in the workspace if you have added it to your primary application classpath.
As GWT build takes ages, we invested some money in a JRebel license. We have two separate Eclipse projects for our back-end and our GWT front-end. JRebel reloads the classes automatically and I never need to restart my local server while writing code. It proved to be a wonderful time saver. Definitely worth the investment.

Statically linking maven and gradle dependencies

I am using the hector & astyanax projects. These projects used to require maven, and now astyanax requires gradle.
I would like to statically link one of these projects to my java project (which is not built using maven/gradle). I am not interested in updating the version of astyanax every time they make a new release. I am not interested in mavenizing/gradelizing my own project.
So, two problems arise: 1. Getting the astyanax jars. 2. Getting the depenedency Jars.
At first, not having time to thoroughly understand maven (get off my lawn!), I copied all of the jar files in my global .maven directory into my project, and linked to them. Problem is, it's a pretty messy solution.
Is there an easier way to get all jars needed to use a gradle/maven library? (While I don't mind using gradle to build astyanax, I don't want to use it to build my own project).
Getting jars for distribution, seems like a very basic use case, am I missing a simple way here?
astyanax is published to maven central as com.netflix.astyanax:astyanax:1.56.42. Any build tool (Grails, Maven, Gradle, Buildr, SBT) that resolves from Maven can make a dependency on Astyanax and have its dependencies transitively downloaded. That fact that it's built with Gradle doesn't change how it's consumed.
From your question, it's unclear how you want to resolve these libraries. If you don't want to use a tool (Grails, Maven, Gradle, Buildr, SBT), then you'll have to manually navigate every dependencies and its dependencies from Maven Central. It's quite uncommon for a modern java project to manually download dependencies anymore, the practicalness given the complex dependencies graph make it prohibitive.

Using OSGI bundles with sbt or maven

I had this crazy idea since a long time so decided to finally ask. Is there some project for integrating bundles directly into the the build process without explicitly doing extra work of including an osgi container and adding bundles etc. So the basic idea being in you build.sbt or pom.xml you just specify your dependency like you normally do and instead of fetching the jars, sbt or mvn fetches bundles (if available) for your dependency. And on building the project a container of your choice would be downloaded and bundles (and jars) would be added to it automatically ? Just like a fairy tale.
EDIT: By the last part i meant something along the lines of felix gogo which will create a script for adding bundles to run container with them. Althogh thats too much to ask for but after the build i can just run a script and my whole project will run on an osgi container free from jar hell.
This already works today. You simply use the maven bundle plugin to create a bundle of your code during the build process. Many of the jars in maven central already are bundles. So you just specify them as normal dependencies.
I am not sure what you want to achieve in the last part. Downlaoding the container and adding the bundles. The build process just creates the jar. Why should it load a container?
If you want to do this for testing purposes then pax exam is what you search. It does exactly what your describe for your unit tests. It downloads a container, adds your bundles and deploys and runs your test in the container.

Resources