Trying to access JNDI from a OSGi-based plugin failed for me with the following exception:
java.lang.ClassNotFoundException: org.apache.naming.java.javaURLContextFactory
To rectify the situation I first tried to add something along the lines of "org.apache.naming.*;version="0.0"" to the Import-Package instruction of atlassian-plugin.xml. This however, seems to be ignored by the plugin system as it doesn't yield a corresponding MANIFEST.MF-entry in the .osgi-plugins/transformed-plugins version of my .jar.
Subsequently I tried various variants of this instruction as well as adding the "magic" *;resolution:=optional
instruction. Still without success.
Finally, I was able to force the plugin-system to include the required class by embedding a reference to it in the plugin-sourcecode:
public static Class<?> foo = org.apache.naming.java.javaURLContextFactory.class;
While this now led to the correct Import-Package entry in MANIFEST.MF (org.apache.naming;version="0.0",org.apache.naming.java;version="0.0"), it incited the runtime-wrath of the plugin-system:
com.atlassian.plugin.osgi.container.OsgiContainerException: Cannot start plugin: com.levigo.jira.levigo-avatars-plugin
...
Caused by: org.osgi.framework.BundleException: Unresolved constraint in bundle com.levigo.jira.levigo-avatars-plugin [74]: Unable to resolve 74.0: missing requirement [74.0] package; (&(package=org.apache.naming)(version>=0.0.0))
Does anybody have an idea how this is supposed to work? I would have expected the prerequisites for JNDI to come from the system bundle. If those don't, how can I get them?
Community moderators have prevented the ability to post new answers.
Ok, here is the example, very basic:
package com.mycompany.silexample; /** * This is the bundle activator. Since it's OSGI, it will boot in the same * directory as any Jira plugin (JIRA_HOME/plugins/installed-plugins/) * * @author Radu Dumitriu * @since 1.0 */ public class BundleActivator implements org.osgi.framework.BundleActivator { /** * Default constructor */ public BundleActivator() { } /** * Standard OSGI startup hook * @param bundleContext the bundle context */ public void start(org.osgi.framework.BundleContext bundleContext) { try { javax.naming.InitialContext ctx = new javax.naming.InitialContext(); Object o = ctx.lookup("java:comp/env/jdbc/JiraDS"); System.out.println("Hey! It works! Returned:" + o); } catch(Exception ex) { System.err.println("oops!" + ex); } } /** * Standard OSGI shutdown hook * @param bundleContext the bundle context */ public void stop(org.osgi.framework.BundleContext bundleContext) { //does nothing } }
Now, the pom.xml:
<?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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.mycompany</groupId> <artifactId>silexample</artifactId> <version>1.0</version> <name>silexample</name> <description>Example.</description> <packaging>jar</packaging> <properties> <jira.version>4.3</jira.version> <jira.data.version>4.3</jira.data.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>com.atlassian.jira</groupId> <artifactId>atlassian-jira</artifactId> <version>${jira.version}</version> <scope>provided</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> <plugin> <artifactId>maven-jar-plugin</artifactId> <configuration> <verbose>true</verbose> <archive> <manifestFile> ${project.build.outputDirectory}/META-INF/MANIFEST.MF </manifestFile> </archive> </configuration> </plugin> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <configuration> <supportedProjectTypes> <supportedProjectType>jar</supportedProjectType> <supportedProjectType>bundle</supportedProjectType> </supportedProjectTypes> <instructions> <Bundle-SymbolicName>${project.groupId}.${project.artifactId}</Bundle-SymbolicName> <Bundle-Name>${project.name}</Bundle-Name> <Bundle-Version>${project.version}</Bundle-Version> <Export-Package> com.mycompany.silexample.* </Export-Package> <Bundle-Activator>com.mycompany.silexample.BundleActivator</Bundle-Activator> </instructions> </configuration> <executions> <execution> <id>bundle-manifest</id> <phase>process-classes</phase> <goals> <goal>manifest</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <reporting> <plugins> <plugin> <artifactId>maven-javadoc-plugin</artifactId> </plugin> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>taglist-maven-plugin</artifactId> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.4.3</version> <configuration> <argLine>-Xms128m -Xmx256m</argLine> </configuration> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-project-info-reports-plugin</artifactId> <version>2.1.1</version> </plugin> </plugins> </reporting> </project>
The output:
# tail -n 2000 ../../../logs/catalina.out | grep "It works"
Hey! It works! Returned:org.apache.tomcat.dbcp.dbcp.BasicDataSource@61a2d734
Hm. it's full of brs but I imagine it's good enough. HTH
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
There are some things that you should be aware. From REST annotated classes, it will give you error (Classloader on the generated proxy is wrong)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
What I meant with the last comment:
ClassLoader origCL = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(ComponentManager.class.getClassLoader());
//::TODO:: do lookup here
} finally {
Thread.currentThread().setContextClassLoader(origCL);
}
See which solution suits you.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Yes, I, too, totally suspect the CCL, since I saw that you acces JNDI from the BundleActivator which I don't. I tried to access it from a ServletFilter. It may very well be that the CCL is messed up for those.
I'm currently stuck with some other issues, but I hope to get around testing your solution later today.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Well, indeed indeed the problem was simply that ServletFilters are not called with the OSGi bundle class loader set as the context class loader. Setting it using the idiom you mentioned in your commentdid the trick!
Thanks a lot for your help!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
very very Thanks Radu, it works for me
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I tried this code but I get
java.lang.reflect.InvocationTargetException ... Caused by: java.lang.ClassNotFoundException: com.atlassian.jira.ComponentManager
I can't add com.atlassian.jira to the imported packages.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Radu Dumitriu, can you give me some light about why this works? I used this solution to solve the problems I mention in: https://answers.atlassian.com/questions/53759022
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You're guessing wrong.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I'm having the same problem here. Did someone figure out how to use a tomcat jndi datasource?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Also having the same problem. Is there an update to this? I noticed that the pom is referencing jira 4.4 and the answer is from 2011.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hello,
Cannot use org.apache.naming.java.javaURLContextFactory ?
No problem, just refrain and use standard JNDI classes.
Something like:
Context context = ctx != null ? ctx : new InitialContext();
try {
return context.lookup(name);
} catch(Throwable t) { ............
}
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
FYI:
OSGI is exporting a limited number of packages. org.apache.naming is not among them. Normally, you should be able to control what's being exported, but this will probably come in the future.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thanks for your help! I am using the standard JNDI lookup method. The problem isn't that I want to use org.apache.naming.java.javaURLContextFactory, it is Tomcat. In other words: the org.apache.naming.java.javaURLContextFactory is the JNDI context factory implementation that will be used if you try to do the JNDI lookup the way you proposed it, hence the "standard JNDI lookup" method doesn't work.
I have since come to the conclusion that there is simply no way to use JNDI from a Version 2 plugin without major source-code hacking.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
The OSGI error is: com.levigo.jira.levigo-avatars-plugin [74]: Unable to resolve 74.0: missing requirement
which means your plugin is to be blamed for that.
If you are setting up your environment for lookups, something like:
System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory");
System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming");
then you're on the wrong path. Remove that code
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I thought that I had made it clear that I don't have something like
System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming");
in my code. The code I cited in the original message is the very code I am using. There is no System.setProperty(...) or whatever involved.
Have you ever successfully accessed JNDI from a Version 2 (OSGi) plugin? The way I see it, this simple isn't possible since neither the system bundle nor any other bundle exports a viable JNDI naming factory implementation.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I thought that I had made it clear that I don't have something like
System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming");
in my code. The code I cited in the original message is the very code I am using. There is no System.setProperty(...) or whatever involved.
Have you ever successfully accessed JNDI from a Version 2 (OSGi) plugin? The way I see it, this simple isn't possible since neither the system bundle nor any other bundle exports a viable JNDI naming factory implementation.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi. For me it works. I can access from my plugin all kinds of JNDI resources.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Jorg, I promise that, if I will have some time tomorrow, I will post some source code.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Radu, thanks. I'm really looking forward to learning how you did it. Did you configure your plugin with the Atlassian plugin descriptor or using MANIFEST.MF?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.