How to configure OSGI in IntelliJ when it's handled by Maven - maven

I'm an OSGI newb.
I can really use any guidance I can get regarding IntelliJ IDEA / OSGI / Maven / Sling.
So the actual Felix plugin dies when I load it. Apparently it hasn't been maintained and is no longer compatible with the latest release by which I mean IntelliJ IDEA 13.
So I've configured the framework to felix-framework-4.2.1, and that seems to work fine. My greatest concern is that if I apply the OSGI facet to a bundle, the settings seem to indicate that it will change the bundle. Since we have this set up in Maven, I don't think we want this. The source of the facet seems to be the Osmorc plugin. When I used it before, there were complaints about some packages in maven that weren't OSGI enabled and the IDE wanted to point to a special Spring repository for OSGI enabled jar dependencies.
Since we are doing this in Maven, should I even bother with Osmorc? Is there a better way to manage OSGI in IntelliJ IDEA? It is handy knowing which packages are OSGI enabled but an error for that? Really? Specifically I am referring to "The package is not exported by the bundle dependencies" showing up on imports and annotations.

My personal observation with Intellij IDEA 13 is that the OSGI project inspector is slightly more aggressive when it comes to profiling your classes that utilize non-osgi exported classes. That being said, a way around this is by adjusting the inspector severity level. This enables you to use the same OSGI-based approach you were using in Intellij IDEA 12.
To do this, go into your project settings (on Mac: Command+,) and then navigate to the following node:
Inspections --> OSGI --> Package accessibility
Once selected, you'll be able to change the severity level from error to warning.
Performing this change is requisite on a few changes in your pom.xml:
<dependencies>
.
.
<dependency>
<groupId>com.pkg.name</groupId>
<artifactId>some-non-osgi-artifact</artifactId>
<version>0.1-EXAMPLE</version>
</dependency>
</dependencies>
<build>
<plugins>
.
.
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>${maven-bundle-plugin.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Export-Package>
you.know.what.goes.here
</Export-Package>
<Private-Package>you.know.what.goes.here</Private-Package>
<Import-Package>
*
</Import-Package>
<Embed-Dependency>some-non-osgi-artifact;scope=compile|runtime;inline=false</Embed-Dependency>
<Embed-Transitive>true</Embed-Transitive>
<Embed-StripGroup>true</Embed-StripGroup>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
Hope this helps,
Ajay

I think your best bet currently is to use the maven bundle plugin to manage your imports and exports. This means intellij will simply see your bundles as maven projects. Still the correct jars should result. I handle OSGi bundles the same way in eclipse and it works fine.
I also read on the OSGi dev mailing list that there is a bndtools for intellij planned but this will for sure take a while.

Related

How to deal with dependencies with "provided" scope in OSGi

There are lots of tutorials, which shows how to cope with dependencies of the OSGi project and how should they be converted to the bundle. After more than one day research, I have still not found how to deal with the dependencies with provided scope.
Let me give an example. I am currently using Dropbox (dropbox-core-sdk 3.0) and it has two dependencies (com.google.android and javax.servlet) with provided scope. When I use the techniques such as maven-bundle-plugin or bnd, it only downloads the artifacts and its transitive dependencies. However, I need also provided dependencies in order to be able to import my project to the OSGi container.
I am using maven-bundle-plugin and my pom.xml looks like:
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId};singleton:=true</Bundle-SymbolicName>
<Bundle-Version>${project.version}</Bundle-Version>
<Export-Package>*</Export-Package>
<Embed-Transitive>true</Embed-Transitive>
<Embed-Dependency>*</Embed-Dependency>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
even if Embed-Dependency says include everything, only the dependencies + transitive dependencies are in the jar. However, I want the provided-scoped jars are also in the jar.
Is there any way to download dependencies with provided scope. If not, how to deal with this situation?
I would have to defer to the Maven BND experts out there, but I don't think you can include provided dependencies through a Maven build. Since it is unlikely you will be using the Android components outside of your bundle, couldn't you just manually download the needed Jars and place them in your bundle (Bundle-Classpath)?
I think you can specify the scopes of the dependencies you want to embed. Be careful though that some dependencies like the OSGi spec jars should never be deployed.
In general you may only embed dependencies that are hidden inside the bundle. Any packages that are needed to talk to other bundles should better not deployed.
For example the servlet api is typically provided by the httpservice bundle you use.
Try this option:
<Embed-Dependency>*;scope=compile|provided</Embed-Dependency>

Sling deploy content and bundle with maven

Iam searching for a maven based solution to deploy apache sling bundle and content (including jsp/html, etc files) on my sling standalone server.
I stated this private project to learn about sightly and sling models without using AEM. It is my first only sling project.
Ive created a sling bundle and a sling content project from the specific archetypes. Ive stated working with the Eclipse Sling IDE tools, but iam used to IntelliJ and there is no plugin to deploy the contetent the same way. I think its possible to build and deploy a package with both (bundle and content) by using maven.
Hopefully someone of you have some instructions or ideas to solve this problem and make it more comfortable developing web projects with apache sling.
Cheers ;)
The maven-sling-plugin can install bundles in a Sling instance, and bundles can include initial content which is installed when they become active.
The slingbucks sample demonstrates this, if you build it as shown below it will be installed in the Sling instance running on port 8080 and its initial content (defined under src/main/resources/SLING-CONTENT as specified in that module's pom.xml) will be installed:
mvn clean install org.apache.sling:maven-sling-plugin:install -Dsling.url=http://localhost:8080/system/console
If you use the Sling parent pom you can also use the autoInstallBundle profile to do the same thing using the default URL that that pom defines:
mvn clean install -P autoInstallBundle
This project may help you https://github.com/auniverseaway/slick, see the pom.xml file there
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.0.1</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Sling-Initial-Content>
jcr_root/content;
overwriteProperties:=false;
overwrite:=false;
uninstall:=false;
path:=/content;
maven:mount:=false,
jcr_root/apps/slick;
overwrite:=true;
path:=/apps/slick;
maven:mount:=false,
jcr_root/apps/sling;
overwrite:=true;
path:=/apps/sling;
maven:mount:=false,
jcr_root/etc;
path:=/etc;
overwriteProperties:=false;
uninstall:=false,
jcr_root/i18n;
path:=/etc/i18n/net.zum.slick;
overwrite:=true;uninstall:=true
</Sling-Initial-Content>
<Bundle-Activator>net.zum.slick.internal.Activator</Bundle-Activator>
<Sling-Model-Packages>
net.zum.slick
</Sling-Model-Packages>
</instructions>
</configuration>
</plugin>
All in all the files inside the directories defined in <Sling-Initial-Content> space of the maven-bundle-plugin will be deployed with the bundle, correct?

How to avoid "The package is not exported by the bundle dependencies" error in IntelliJ IDEA?

I have created a new Maven project using the CQ5 archetype and imported it into IntelliJ IDEA. IntelliJ marks usages of some classes such as org.apache.felix.annotations.Component, org.apache.felix.annotations.Reference, etc. IntellIJ as erroneous with the following error message:
The package is not exported by the bundle dependencies
Is this a legitimate error?
How can I fix it (as opposed to disabling the inspection)?
I'm using version 12.1.4
The error seems legit. I'm not able to find that package in the ACQ 5.6.1 Doc.
I turn off the inspection by:
Right-clicking on the block in the right margin.
Click "Customize Highlighting level".
Bring the slider down to "None".
Are you exporting those packages as part of the bundle definition? In the maven project, you should have the maven bundle plugin with <Export-Package>your.packages.here</Export-Package> defined. Are these packages included in that definition? If not, those services won't actually be availale in OSGi.
In my case, I accidentally "configured OSGi" when I only wanted to configure Spring. The way I dealt with this issue was by right clicking the right margin at one of the affected lines, clicking "Customize Highlighting Level" --> "Configure Inspections". I think hippoLogic's solution will get rid of all your syntax-level error highlighting as well as helpful inspection-level highlighting. This way you can simply tune the latter to exclude OSGi.
It'd be even better to de-configure OSGi (which I haven't investigated), but here's a quick/dirty fix to reduce the highlighting noise.
To Fix this check if the respective dependencies are present in the pom file, in your case I think it mught be present since you just imported them up from eclipse where it wasn't giving any error. Also check if the settings.xmml being referred to is correct, and is in right place and the correct one is been referred from intellij. your settings.xml is present in the maven home or might be reffered as a symbolic link in the maven home. Hope this helps.
just export related packages on maven build plugins as #Brenn's answer, deteails as below:
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>${maven.bundle.version}</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Bundle-DocURL>${project.url}</Bundle-DocURL>
<Bundle-Activator>
org.apache.tika.parser.internal.Activator
</Bundle-Activator>
<Import-Package>
org.w3c.dom,
org.apache.tika.*,
*;resolution:=optional
</Import-Package>
<Export-Package>
your package here
</Export-Package>
</instructions>
</configuration>
</plugin>
I work on a project clone from github, it's unrelated about OSGI, so i think that's a bug of idea or i accidentally turn on . Then i assume the feature of "OSGI" in idea work depend on plugin,so i diabel this plugin
Disable the OSGI plugin, the error message disappear.
in mac os:
command + shift + a, type plugin
search "OSGI", then disable this plugin.

install osgi dependencies via maven bundle and sling plugins

I have an osgi-bundle which is created by using the maven-bundle-plugin:
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
<Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
</instructions>
</configuration>
</plugin>
The bundle is installed via the maven-sling-plugin.
I have a fasterxml.jackson dependency which exists as an osgi-bundle in my .m2 repo and acts as a dependency in my project.
How can I make maven deploy this dependency as an osgi-bundle as well?
At the moment I have to install it manually in my osgi-container.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.2.2</version>
</dependency>
EDIT:
Simplification:
How do I make maven realize that an osgi-bundle which I refer to as a dependency in my pom.xml shall be installed in the osgi-container along with the bundles that depend upon it?
You'll probably find its best to package your bundle as part of your application along with the /content, /apps portions of your application in the /apps/myapp/install folder will cause the libraries to be installed as bundles by the jcr installer provider.
There are a couple of ways of automating packaging/deployment of applications using maven described in these articles:
http://www.cognifide.com/blogs/cq/maven-plugin-automating-deployments-of-crx-cq-applications/
http://mkalugin-cq.blogspot.co.uk/2012/11/how-to-use-maven-project-to-create.html
http://labs.sixdimensions.com/blog/dklco/2012-05-03/introducing-cq-deploy-maven-plugin-deploying-cq-projects
http://dev.day.com/docs/en/cq/current/core/how_to/how_to_use_the_vlttool/vlt-mavenplugin.html
Alternatively, you could just use the CRXDE to place the bundles and then CRX Package Manager to test the approach, them move on to automated packaging later.
If you don't want to repackage the two OSGI bundles, you can use the sling maven plugin to install the jackson bundle directly
mvn org.apache.sling:maven-sling-plugin:install-file -Dsling.file=jackson-databind-2.2.2.jar

How can I share non-OSGi libraries between bundles in an OSGi container?

I came across this question when trying to share the Struts packages among multiple bundles inside an OSGi container. I wanted to avoid both duplicating dependencies inside the bundles and introducing a new dependency between them (by having one bundle export its internal dependencies for the other to share).
It turns out the answer is very easy if you happen to use Maven, and if you aren't, you can still use the Maven solution to learn how to create the same result with some other mechanism.
I found this approach useful multiple times during my project, so I'll post an example here.
An additional path for those not so keen on maven, unable to port, or perfectly happy with ant/ivy
I've found the that easiest way to accomplish the stated task is to turn the non-OSGi library into an OSGi library by letting the manifest export every package and add on some approriate symbolic names / versions. I've been able to do this VERY easily with bnd via ant tasks (or even direct command line invocation). There are also repositories which contain "osgi-ified" version of many popular libraries. Some libraries (joda-time) are already shipping with correct OSGi manifests.
Using Maven, it is very easy to create an OSGi bundle from any library. However, I think the same result can be created with other mechanisms, too. The Maven solution helped me understand how it works.
Creating the bundle is done by creating a project which has the library as a dependency and then packaging the project using the maven-bundle-plugin from the Apache Felix project and specifying the library packages with the Export-Package instruction. I used this to share Google Protocol Buffers between bundles inside an OSGi container:
<?xml version="1.0" encoding="UTF-8" ?>
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example.lib</groupId>
<artifactId>protobuf-dist</artifactId>
<version>2.1.0</version>
<name>Google Protocol Buffers OSGi Distribution</name>
<packaging>bundle</packaging>
<dependencies>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>2.1.0</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
<configuration>
<instructions>
<Export-Package>com.google.protobuf</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>
</project>
If you want all transitive dependencies rolled into the bundle, too, use the bundleall goal of the plugin.
The plugin recognizes and honours existing OSGi manifests in the dependency.
You can also use the bundle plugin to just create the manifest and tell the jar packaging plugin (or the jar-with-dependencies builtin assembly) to use that manifest via the archive section. The plugin's page linked above shows how to do that.

Resources