8 Replies Latest reply on Dec 5, 2012 9:02 AM by cberger

    [JBoss AS 7.2.0 alpha] How to access JNDI from within a service component?

    cberger

      Hi guys,

       

      I'm using the Declarative Service Model and I want to access a datasource via JNDI. The datasource is available at java:jboss/datasources/TestDS.

       

      The service component looks like this:

       

      @Component(configurationPolicy = ConfigurationPolicy.require)
      public class JndiDataSource implements DataSource {
      
          private InitialContext initialContext;
          private DataSource dataSource;
      
      
          @OCD(id = "com.xx.xxx.database.datasource.jndi.JndiDataSource", factory = true)
          private interface Config {
              String MIN_SIZE_1 = "\u001f{\"minSize\":1}";
      
              @AD(name = "JNDI Name", description = "JNDI Name for obtaining the DataSource" + MIN_SIZE_1, deflt = "java:jboss/datasources/TestDS")
              String name();
      
              @AD(name = "Database Usage", required = false, description = "Database Usage" + MIN_SIZE_1, deflt = "main")
              String usage();
          }
      
      
          @Reference
          private void setInitialContext(final InitialContext initialContext) {
              this.initialContext = initialContext;
          }
      
      
          @Modified
          @Activate
          private void activate(final Map<String, ?> propertyMap) throws NamingException {
              final Config config = Configurable.createConfigurable(Config.class, propertyMap);
              dataSource = (DataSource) initialContext.lookup(config.name());
          }
      

       

      The datasource is available, I've checked this via the admin web console and the bundle which contains the service component is up and active.

       

      However, the state of the component still remains in unsatisfied.

       

       

      g! scr:info 9ID: 9
      Name: com.xxx.xxx.database.datasource.jndi.JndiDataSource
      Bundle: xxx-database-datasource-jndi (85)
      State: unsatisfied
      Default State: enabled
      Activation: delayed
      Configuration Policy: require
      Activate Method: activate (declared in the descriptor)
      Deactivate Method: deactivate
      Modified Method: activate
      Services: javax.sql.DataSource
      Service Type: service
      Reference: initialContext
          Satisfied: unsatisfied
          Service Name: javax.naming.InitialContext
          Multiple: single
          Optional: mandatory
          Policy: static
      Properties:
          component.id = 9
          component.name = com.xxx.xxx.database.datasource.jndi.JndiDataS
      ource
      

       

      As you can see, the service initialContext is unsatisfied, too. So I guess that's the blocker of my component. Why is the initialContext not available?

        • 1. Re: [JBoss AS 7.2.0 alpha] How to access JNDI from within a service component?
          thomas.diesler

          I believe BundleActivator is the only component injection target that we support.

          • 2. Re: [JBoss AS 7.2.0 alpha] How to access JNDI from within a service component?
            cberger

            Hmm that's strange, because it worked with JBoss 7.1.1.

            • 3. Re: [JBoss AS 7.2.0 alpha] How to access JNDI from within a service component?
              thomas.diesler

              In that case forget what I just said. Could you provide a sample deployment that isolates this issue and allows me to reproduce what you are seeing?

              • 4. Re: [JBoss AS 7.2.0 alpha] How to access JNDI from within a service component?
                cberger

                Hi Thomas,

                 

                I did a research and I compared the registered services from the system.bundle of JBoss AS 7.1.1 and JBoss AS 7.2.0alpha.

                 

                That's the result of JBoss AS 7.1.1 (the whole log is in the attachment (jboss711.log)

                 

                20:22:59,214 INFO  [com.mwaysolutions.gofer.test.Activator] (telnetconsole.shell remote=/127.0.0.1:60055) symbolicName: system.bundle, objectClass: [javax.transaction.TransactionManager]

                20:22:59,214 INFO  [com.mwaysolutions.gofer.test.Activator] (telnetconsole.shell remote=/127.0.0.1:60055) symbolicName: system.bundle, objectClass: [javax.transaction.UserTransaction]

                20:22:59,214 INFO  [com.mwaysolutions.gofer.test.Activator] (telnetconsole.shell remote=/127.0.0.1:60055) symbolicName: system.bundle, objectClass: [javax.naming.spi.InitialContextFactoryBuilder]

                20:22:59,229 INFO  [com.mwaysolutions.gofer.test.Activator] (telnetconsole.shell remote=/127.0.0.1:60055) symbolicName: system.bundle, objectClass: [javax.naming.InitialContext]

                20:22:59,229 INFO  [com.mwaysolutions.gofer.test.Activator] (telnetconsole.shell remote=/127.0.0.1:60055) symbolicName: org.apache.felix.gogo.command, objectClass: [org.apache.felix.gogo.command.OBR]

                20:22:59,229 INFO  [com.mwaysolutions.gofer.test.Activator] (telnetconsole.shell remote=/127.0.0.1:60055) symbolicName: org.apache.felix.gogo.command, objectClass: [org.apache.felix.gogo.command.Files]

                20:22:59,229 INFO  [com.mwaysolutions.gofer.test.Activator] (telnetconsole.shell remote=/127.0.0.1:60055) symbolicName: org.apache.felix.gogo.command, objectClass: [org.apache.felix.gogo.command.Inspect]

                20:22:59,229 INFO  [com.mwaysolutions.gofer.test.Activator] (telnetconsole.shell remote=/127.0.0.1:60055) symbolicName: org.apache.felix.gogo.command, objectClass: [org.apache.felix.gogo.command.Basic]

                20:22:59,229 INFO  [com.mwaysolutions.gofer.test.Activator] (telnetconsole.shell remote=/127.0.0.1:60055) symbolicName: org.apache.felix.scr, objectClass: [org.apache.felix.scr.impl.ScrG

                 

                As you can see, the system.bundle is providing the javax.naming.InitialContext

                 

                Now, the log of JBoss 7.2.0alpha (jboss720.log)

                 

                20:43:50,363 INFO  [stdout] (MSC service thread 1-7) symbolicName: org.jboss.osgi.framework, objectClass: [javax.xml.parsers.DocumentBuilderFactory]

                20:43:50,363 INFO  [stdout] (MSC service thread 1-7) symbolicName: org.jboss.osgi.framework, objectClass: [javax.xml.parsers.SAXParserFactory]

                20:43:50,363 INFO  [stdout] (MSC service thread 1-7) symbolicName: org.jboss.osgi.framework, objectClass: [javax.naming.spi.InitialContextFactoryBuilder, org.jboss.as.naming.InitialContextFactoryBuilder]

                20:43:50,363 INFO  [stdout] (MSC service thread 1-7) symbolicName: org.jboss.osgi.framework, objectClass: [javax.transaction.UserTransaction]

                20:43:50,363 INFO  [stdout] (MSC service thread 1-7) symbolicName: org.jboss.osgi.framework, objectClass: [javax.transaction.TransactionManager]

                20:43:50,363 INFO  [stdout] (MSC service thread 1-7) symbolicName: org.jboss.osgi.framework, objectClass: [javax.management.MBeanServer]

                20:43:50,363 INFO  [stdout] (MSC service thread 1-7) symbolicName: org.jboss.osgi.framework, objectClass: [org.jboss.msc.service.ServiceContainer]

                20:43:50,363 INFO  [stdout] (MSC service thread 1-7) symbolicName: org.jboss.osgi.framework, objectClass: [org.jboss.as.controller.client.ModelControllerClient]

                20:43:50,363 INFO  [stdout] (MSC service thread 1-7) symbolicName: org.jboss.osgi.framework, objectClass: [org.jboss.osgi.repository.XRepository, org.osgi.service.repository.Repository]

                20:43:50,363 INFO  [stdout] (MSC service thread 1-7) symbolicName: org.jboss.osgi.framework, objectClass: [org.jboss.osgi.deployment.interceptor.LifecycleInterceptorService]

                20:43:50,363 INFO  [stdout] (MSC service thread 1-7) symbolicName: org.jboss.osgi.framework, objectClass: [org.osgi.service.packageadmin.PackageAdmin]

                20:43:50,363 INFO  [stdout] (MSC service thread 1-7) symbolicName: org.jboss.osgi.framework, objectClass: [org.jboss.osgi.repository.RepositoryStorageFactory]

                20:43:50,363 INFO  [stdout] (MSC service thread 1-7) symbolicName: org.jboss.osgi.framework, objectClass: [org.jboss.osgi.repository.XRepository, org.osgi.service.repository.Repository]

                20:43:50,363 INFO  [stdout] (MSC service thread 1-7) symbolicName: org.jboss.osgi.framework, objectClass: [org.osgi.service.url.URLStreamHandlerService]

                20:43:50,363 INFO  [stdout] (MSC service thread 1-7) symbolicName: org.jboss.osgi.framework, objectClass: [org.osgi.service.startlevel.StartLevel]

                20:43:50,363 INFO  [stdout] (MSC service thread 1-7) symbolicName: org.jboss.osgi.framework, objectClass: [org.jboss.osgi.deployment.interceptor.LifecycleInterceptor]

                 

                As you can see, there is no javax.naming.InitialContext anymore!

                 

                And now I know fore sure, im not able to configure my component because of the missing service registration. However, I also added a test case where you can reproduce the issue.

                 

                Bundle:                                                  Description:

                gofer-test-1.0.0                                       This bundle writes all registered services to the logfile

                gofer-database-datasource-jndi                 That's the bundle which I want to configure. It includes the service component. (actually i want to configure the component not the bundle )

                bndlib                                                     You need this because I'm using bnd annotations

                org.apache.felix.scr-1.6.2                         obviously, the SCR

                org.apache.felix.gogo.command                if you want to check the configuration via the gogo shell

                org.apache.felix.gogo.runtime

                org.apache.felix.gogo.shell

                org.apache.felix.shell.remote

                 

                If you want to use the gogo-shell, you also have to configure system-properties like this:

                 

                  <system-properties>

                        <property name="osgi.shell.telnet.ip" value="127.0.0.1"/>

                        <property name="osgi.shell.telnet.port" value="8023"/>

                    </system-properties>

                 

                Now you can call the shell via telnet localhost 8023.

                 

                1) lb jndi to list the jndi bundle

                2) scr:list [ID of Bundle] to get the components which are included in this bundle

                3) scr:info[ID of component] to get a detailed overview

                 

                If I configure the component com.mwaysolutions.gofer2.database.datasource.jndi.JndiDataSource with the help of the gogo-shell like this: (It should also be possible to use the jboss config admin web gui)

                 

                cm:createFactory com.mwaysolutions.gofer2.database.datasource.jndi.JndiDataSource null name String "java:jboss/datasources/GoferDS" usage String main

                 

                Then it's working in JBoss AS 7.1.1. The component reach the state registered, but not in JBoss As 7.2.0alpha. But as we know, it's because of the missing javax.naming.InitialContext service.

                 

                Anyway, I would appreciate any fast fix for this.

                 

                Thanks in advance.

                 

                If you need any support or more information, please feel free to contact me.

                 

                cheers

                 

                christian

                 

                TestCase: https://www.dropbox.com/s/t674fwm2h5wzve8/TestCase.zip

                 

                BTW: There is no upload function at all if you just press reply

                • 5. Re: [JBoss AS 7.2.0 alpha] How to access JNDI from within a service component?
                  thomas.diesler

                  Yes, we removed the InitialContext service because it is not part of the Enterprise OSGi JNDI contract.

                   

                  Have a look at

                   

                  * 126 JNDI Services Specification

                   

                  in the r4.2.enterprise spec. This defines how bundles should interact with JNDI.

                  We have examples in jbosgi.

                  • 6. Re: [JBoss AS 7.2.0 alpha] How to access JNDI from within a service component?
                    cberger

                    Hi Thomas,

                     

                    Yes, we removed the InitialContext service because it is not part of the Enterprise OSGi JNDI contract.

                     

                    ok that's interesting, because the InitialContext-Service is also availabe in the Apache Felix Framework implementation. However, if it's not spec complaint it is a good decision to remove it.

                    Now I'm using the InitialContextFactoryBuilder-Service and it's working. But I don't understand why do I have to cast to a proprietary org.jboss.as.naming.InitialContext and not to javax.naming.InitialContext?

                     

                    initialContext = (InitialContext) initialContextFactory.getInitialContext(null);

                     

                    BTW: It seems there is a bug in the config admin subsystem. I'll try to create a testcase and post it in a new discussion.

                     

                    Thanks

                     

                    Chris

                    • 7. Re: [JBoss AS 7.2.0 alpha] How to access JNDI from within a service component?
                      thomas.diesler

                      Where did you see the cast - its invalid

                       

                      [tdiesler@tdmac jbosgi]$ git grep naming.InitialContext

                      testsuite/example/src/test/java/org/jboss/test/osgi/example/ejb3/StatelessBeanTestCase.java:import javax.naming.InitialContext;

                      testsuite/example/src/test/java/org/jboss/test/osgi/example/jndi/NamingStandaloneTestCase.java:import javax.naming.InitialContext;

                      testsuite/example/src/test/java/org/jboss/test/osgi/example/jndi/NamingTestCase.java:import javax.naming.InitialContext;

                       

                      > It seems there is a bug in the config admin subsystem. I'll try to create a testcase and post it in a new discussion.

                       

                      merci

                      • 8. Re: [JBoss AS 7.2.0 alpha] How to access JNDI from within a service component?
                        cberger

                        Thomas Diesler wrote:

                         

                        Where did you see the cast - its invalid

                         

                        [tdiesler@tdmac jbosgi]$ git grep naming.InitialContext

                        testsuite/example/src/test/java/org/jboss/test/osgi/example/ejb3/StatelessBeanTestCase.java:import javax.naming.InitialContext;

                        testsuite/example/src/test/java/org/jboss/test/osgi/example/jndi/NamingStandaloneTestCase.java:import javax.naming.InitialContext;

                        testsuite/example/src/test/java/org/jboss/test/osgi/example/jndi/NamingTestCase.java:import javax.naming.InitialContext;

                         

                        Maybe I missed the point. I just used this service javax.naming.spi.InitialContextFactoryBuilder to create a factory and a context like this:

                         

                        @Reference

                            private void setInitialContext(final InitialContextFactoryBuilder initialContextFactoryBuilder) {

                                try {

                                    final InitialContextFactory initialContextFactory = initialContextFactoryBuilder.createInitialContextFactory(null);

                                    initialContext = (InitialContext) initialContextFactory.getInitialContext(null);

                                } catch (final NamingException e) {

                                    logger.info(JNDI_DATA_SOURCE + ": {}", e.getMessage());

                                }

                            }

                         

                        I do not understand your test-classes because your are calling a static class NamingSupport from package
                        org.jboss.test.osgi which is not visible for me at github.

                         

                        // Get the InitialContext via {@link JNDIContextManager}

                                JNDIContextManager contextManager = NamingSupport.getContextManager(bundle);

                                Context initialContext = contextManager.newInitialContext();