Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

How do I access JNDI from a Version 2 (OSGi) Plugin?

Jörg Henne August 10, 2011

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?

3 answers

1 accepted

Comments for this post are closed

Community moderators have prevented the ability to post new answers.

Post a new question

7 votes
Answer accepted
Radu Dumitriu
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
September 12, 2011

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

Radu Dumitriu
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
September 12, 2011

Hm. it's full of brs but I imagine it's good enough. HTH

Radu Dumitriu
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
September 12, 2011

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)

Radu Dumitriu
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
September 12, 2011

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.

Jörg Henne September 12, 2011

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.

Jörg Henne September 13, 2011

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!

RambanamP
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
September 18, 2011

very very Thanks Radu, it works for me

Guido Wischrop July 28, 2014

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.

Ernesto Pin February 15, 2017

@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

1 vote
Eric Koepfle June 7, 2013

I am guessing his code didn't really work...

Radu Dumitriu
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
June 7, 2013

You're guessing wrong.

Guido Wischrop July 28, 2014

I'm having the same problem here. Did someone figure out how to use a tomcat jndi datasource?

Dave Gauthier October 2, 2017

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.

0 votes
Radu Dumitriu
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
August 25, 2011

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) { ............
}

Radu Dumitriu
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
August 25, 2011

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.

Jörg Henne August 25, 2011

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.

Radu Dumitriu
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
August 25, 2011

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

Jörg Henne September 11, 2011

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.

Jörg Henne September 11, 2011

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.

Radu Dumitriu
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
September 12, 2011

Hi. For me it works. I can access from my plugin all kinds of JNDI resources.

Radu Dumitriu
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
September 12, 2011

Jorg, I promise that, if I will have some time tomorrow, I will post some source code.

Jörg Henne September 12, 2011

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?

TAGS
AUG Leaders

Atlassian Community Events