I am writing an eclipse plugin with functionality distributed on some modules (core, util, ui etc). During implementing of new launch configuration (launch of course must call functionality from other bundles) for own project type I faced with the problem that this launch starts in new thread and a class that implements launch functionality don't see classes from other bundles and I have NoClassDefFaundError all the time.
I see that classes are loaded with different classloaders and this is OSGI specific behavior. I added necessary dependencies in MANIFEST files and eclipse shows me thats all ok and successfully build my plugins in workspace. But what happens wrong and why this doesn't work?
The problem is due to weird OSGi behavior on classloaders. Eclipse must ensure to have all classes within a single bundle packaged with PDE. So usually restarting IDE environment and rebooting your PC helps. The MANIFEST referring to das schlecht java code has to inject the dependency on a mojo class to the bundle activator. When you have several plugins built with Ant via Eclipse PDE it is unlikely that GI / PD Equinox can resolve the misusage of those. Am i right..or maybe there is another option which is to analyzed further.
Related
I'm struggling to wrap my head around developing OSGI bundles to publish to Karaf. I'm using Netbeans 7.4 and the Create Maven OSGI bundle when creating a new project. I think what I'm wrestling with is dealing with dependencies between different projects and working with them in Netbeans and then publishing to Karaf.
What I'm trying to do is set up a REST web service; I found this tutorial to be a good starting point in getting something basic up and running. So I started setting up a parent project with sub projects (all of these are from the Maven OSGI Bundle template). But after I started deploying bundles to my Karaf instance I started wrestling with the "missing requirement" errors within Karaf. I'd start trying to list each dependency in <Export-Package> or <Embed-Dependency> but it seems like I just keep going farther down and always getting new "missing requirement" messages listing yet another dependency. I then started trying the maven copy-dependencies plugin to export whatever dependencies are used in my project and copying whatever comes out into the Karaf deploy folder, too. That worked for the most part but I'm wrestling with what I think are downstream dependencies of a 3rd party jar, but that's probably a separate question anyway.
So, what I'd like to know is how should I be developing a coherent "application" with this setup? I understand I should separate everything into standalone bundles; i.e., I'll have my REST interface as one, the implementation as another, business logic as another. As a maven project, if I have a dependency for datetime handling or string utilities, maven will handle resolving all of those. But these dependencies won't automatically be included in my OSGI bundle, is that the case? What is the workflow to make sure that everything my project depends on is available to the bundles in Karaf? What about my projects that have other projects as dependencies, i.e., an interface implementation? I would include that project as a dependency so it will compile, but how do I make sure that that dependency is met after it is published?
The mismatch between dependencies at compile time and at deployment time is indeed a problem when working with OSGi.
What you need to know is how these relate to each other. At compile time you have the maven dependencies. When you build your project the maven bundle plugin creates the necessary Import-Package and Export-Package statements for you. Most of the time this simply works and you should avoid tuning too much there by hand.
So after the build the Manifest specifies what the resulting bundle needs but this does not automatically make sure the dependencies are met. So when you deploy the bundle to karaf you get the errors about missing dependencies. This is normal.
Now you need to install other bundles that fulfil these dependencies. Often you can simply install the jars of your maven dependencies (if they are bundles). This does not always work though. So basically you install the bundles and check if the requirements are met now.
The nice thing with karaf is that many bigger dependencies like cxf are already available as features. So it is a good idea to first try to get the dependencies by installing available features before you try to install them bundle by bundle.
So this helps you in getting your dependencies right. Then for "production" use the best solution is to create your own feature file where you refer to the bundles you found.
While installing bundles using the deploy dir seems nice at first it is not a good solution. Better install the bundles directly from maven using the mvn: url syntax karaf provides.
Regarding embedding dependencies. Sometimes it is a good solution but often it only makes things worse as it can lead to package use conflicts which are hard to solve. So better do not embed anything if it is possible.
Very new to eclipse plugin development.
I have converted jar project into eclipse plugin. But I really dont know, how to make use of it. Some basic doubts,
How to call a method available in plugin in our program??
Should every exposed method should be public, in order to use it in our program??
My idea is something like a plugin to sum two numbers. And user installs the plugin and call add(x,y) method in this plugin. Just like calling a method from an included jar.
There are many tutorials explaining how to create a plugin, but i didn't found how to use the same.
What you are describing is a plain OSGi bundle, with no Eclipse-specific features. In terms of the New Plug-in wizard, yours "doesn't contribute to the UI". Technically, it means that it doesn't need plugin.xml.
The way your outside code perceives the bundle is just as if it was a regular jar: you can access its classes, instantiate them, and call their methods. Or you can call static methods, just like you are used to.
The additional layer provided by OSGi means you can identify which Java packages your bundle exports to its users. Therefore a class which is public, but doesn't reside in an exported package, is not accessible to other bundles (this applies only to the strict mode, however; otherwise you only get an Access Restriction warning).
I think this is the situation you are describing...
You have a plugin that you want Eclipse Java (JDT) users to install. In their Java projects, you want them to be able to use some of the Java classes in your plugin.
In Java, a class has to be found on a classpath by a class loader. JDT manages the classpath for projects through "class path containers." The first example of this is when you create a Java project, JDT will add "JRE System Library" as a container. You can see it under the project in the Package Explorer.
Another example of this is the JUnit plugin. You'll notice that when you add a JUnit Test Case to JDT project the first time, a dialog will ask about adding the JUnit library to the build path. (This is an explicit behavior of the JUnit plugin's New File Wizard.) If you agree, you'll see the "JUnit 4" container in the Package Explorer.
Yet another example: PDE expands on what JDT does. When you create a Plugin project, PDE adds a "Plug-in Dependencies" container that it manages based on the plugin dependencies you declare in the plugin manifest.
Users can create and reference their own classpath containers for their favorite libraries.
But, of course, as a library provider, you want to give them one like the JUnit plugin does. To do that, in your plugin:
Add a dependency on JDT Core
Extend from this extension point: org.eclipse.jdt.core.classpathContainerInitializer
If you want a wizard page to create or edit a classpath container entry:
Add a dependency on JDT UI
Extend from this extension point: org.eclipse.jdt.ui.classpathContainerPage
Some plugins use the wizard page to customize the container (JUnit allows picking JUnit 3 or 4); Others just use the page to provide information about the container.
See the JDT documentation topic Setting the Java build path and cross-reference the source code of any examples that familiar to you.
Here is a good article: Simplify Eclipse classpaths using classpath containers
To answer your questions:
You have to add the classes to the classpath using the initialize method of your subclass of ClasspathContainerInitializer.
Yes, methods that you want clients to call must be public and be members of the classes you add to the classpath.
I'm currently developing a maven osgi bundle using Netbeans 7.1. While its easy to create new maven osgi bundle project from netbeans, I've been struggling about how I would run it. Simply running it from netbeans gives me an error that tells me there is missing requirement (missing slf4j for example).
Then I tried a different way. I ran equinox in a terminal and then manually install my project jar to it. But then I must also resolve all the dependencies manually.
Is there any way to automatically download all the required dependencies from an OSGI bundle and install it to a running OSGI framework?
thanx before
AFAIK there's no automation for OSGi in Netbeans (though I may well be wrong). The support you may have seen in Eclipse is only for Eclipse plugins not vanilla OSGi.
Your best bet is to go for some integrating testing or launch via a maven goal, pax-exam or bndtools or even pax-runner will allow you to launch from IDE/maven.
However I don't know of anything that will automatically resolve all dependencies (transitive dependencies and implementations of APIs you depend on would be problematic)
Its a big pain, no question about it. What I used to do was to do a full build (and if you've configured your manifests correctly should include all necessary dependencies) which will generate the necessary jar. I then wired my Tomcat to pick up the jar from my target repository and configured it to hotswap automatically.
Its a matter of preference if you want to run your app server from within your netbeans but I preferred to execute a separate instance of tomcat outside of my IDE. It'll work either way tho.
I am making my firsts steps using osgi and I have a problem with a bundle I created.
I developed 3 bundles in eclipse (they are plugin projects). When I run my bundles inside eclipse using a new and empty target, they work very nice.
Then I tried to export them and run them without eclipse I ran with problems. I created a jar file for each one of them (using export ->deployable plugin) and then I install them in a running equinox container (v3.7.1, from eclipse's plugin directory) and I got a lot of ClassNotFoundExceptions for RuntimeErrorException
this looks like a classpath issue. I think I am not exporting the bundle correctly, but I am not sure.
The problem only happens with 2 of the bundles, which use additional libraries
how can I do it correctly?
In case you need it, this is the full stack
Taking one of the exceptions for example: NoClassDefFoundError on javax.management.RuntimeErrorException.
Did you import the package javax.management in your bundle?
See the following page from the OSGi Community Wiki, it seems directly relevant to your problem: http://wiki.osgi.org/wiki/Why_does_Eclipse_find_javax.swing_but_not_Felix%3F
I've developed an osgi application (no rcp) using eclipse. It consists of several Plugin-Projects-Bundles and dependencies from eclipse plugins folder (commons.* ...)
The application works fine when launched using eclipse.
What is the best way to export and deploy such an application from eclipse? Is there a simple way to export my launch configuration?
All I found was for rcp projects.
All you need to do is religiously fill your Manifest.MF via PDE(Plugin Editor), you must
Add proper plugin-dependencies in the Dependecies tab in PDE
Fill the Classpath and Exported Packages in the Runtime tab
And most importantly, make sure in the Build tab you have checked on the required resources to be exported.
Its very important to note point 3, it is here where most people make mistake and wonder why the project is running perfectly in Eclipse but doesent run when exported.
Right-Click on your
project->Export->Plugin-Development->Deployable
Plugins and Fragments
Check out Chapter 9 on packaging OSGi/Equinox applications in the new OSGi and Equinox book. It's available on rough cuts now: http://my.safaribooksonline.com/9780321561510. It should be available in print for purchase by EclipseCon in March.
Creating an OSGi bundle, by itself, does not constitute a complete application. OSGi bundles require a container and its the container's responsibility to manage the lifetime of the bundle: loading the bundle, resolving dependencies, invoking the bundle's activator, etc. There are several OSGi containers available such as Knopflerfish (http://www.knopflerfish.org/), Felix (http://felix.apache.org/), and Equinox (http://www.eclipse.org/equinox/). Internally, Eclipse uses Equinox.
Deploying an application that uses OSGi entails configuring the container and the exact mechanism for doing that depends on the chosen container. If you wish to continue using Equinox then check out this quick-start guide for configuring and launching the container outside Eclipse (http://www.eclipse.org/equinox/documents/quickstart.php).
PDE generates a configuration that can be customized much easier that writing an Equinox config from scratch. In your running Eclipse-based OSGi environment, type bundles. You'll see where Equinox is putting all the runtime bundles for the launch. In there should be a config.ini that PDE is generating for the launch. In my case it's [workspace root]/.metadata/.plugins/org.eclipse.pde.core/[My Launch Config Name]/config.ini.
-> Create a feature project in Eclipse
-> Open feature.xml file of the created project.
-> Add all the required Plug-ins and dependencies under "Included Plug-ins"
-> Ensure that you have added all OSGI dependant "Plug-ins"
Here is a list of Plug-in I am using
-> Now create the OSGI run configuration
-> Under "Bundles", select your feature project.
Now all the plug-ins can be exported from the Overview tab of your feature.xml