Programmatically creating a JNDI DataSource for Spring

12,982

The org.springframework.test dependency has support for that via the SimpleNamingContextBuilder:

// First create the mock JNDI tree and bind the DS
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
DataSource ds = new ComboPooledDataSource();
ds.setDriverClass( ... ); // etc. for uid, password, url
builder.bind( "java:comp/env/jdbc/MyDS" , ds );
builder.activate();

// Then create the Spring context, which should now be able 
// to resolve the JNDI datasource
ApplicationContext context = new ClassPathXmlApplicationContext( "..." );

That should work.

Cheers,

Share:
12,982
acvcu
Author by

acvcu

Updated on June 05, 2022

Comments

  • acvcu
    acvcu about 2 years

    I have an existing Spring web-based application that has datasources defined using JNDI, and I'm trying to create a standalone app to use the beans. How can I create the JNDI entry and database properties programmatically in the standalone application?

    <bean id="myDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
        <property name="jndiName" value="java:comp/env/jdbc/MyDS" />
    </bean>
    
        public static void main(String[] args) {
    
          // this throws an error since the JNDI lookup fails - can I programmatically define the database properties here?
    
        ClassPathXmlApplicationContext ctx = new  ClassPathXmlApplicationContext("applicationContext.xml");
    
        UserService userService = ctx.getBean(UserService.class);
        User user = userService.findUserById("jdoe");
    
        System.out.println("display name: " + user.getDisplayName());
    }
    

    EDIT:

    I tried something like this, but am now getting the error "javax.naming.NoInitialContextException: Need to specify class name in environment or system property"

    public static void main(String[] args) {
        setupJNDI();
    
        ClassPathXmlApplicationContext ctx = new  ClassPathXmlApplicationContext("applicationContext.xml");
    
        UserService userService = ctx.getBean(UserService.class);
        User user = userService.findUserById("jdoe");
    
        System.out.println("display name: " + user.getDisplayName());
    }
    
    
    private static void setupJNDI() {
        InitialContext ic;
        try {
            ic = new InitialContext();
            ic.createSubcontext("java:");
            ic.createSubcontext("java:/comp");
            ic.createSubcontext("java:/comp/env");
            ic.createSubcontext("java:/comp/env/jdbc");
            SQLServerConnectionPoolDataSource myDS = new SQLServerConnectionPoolDataSource();
            opaDS.setServerName("myserver");
            opaDS.setPortNumber(1433);
            opaDS.setUser("user");
            opaDS.setPassword("password");
    
            ic.bind("java:/comp/env/jdbc/MyDS", myDS);
        } catch (NamingException e) {
            e.printStackTrace();
        }
    }
    
  • acvcu
    acvcu over 11 years
    I tried this but am getting the error 'Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myDataSource' defined in class path resource [applicationContext.xml]: Invocation of init method failed; nested exception is javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial'
  • Anders R. Bystrup
    Anders R. Bystrup over 11 years
    My bad, the JNDI tree should of course be created and activated before trying to create the Spring context - I've edited the answer accordingly.
  • enes.acikoglu
    enes.acikoglu over 6 years
    Could you give me a reasonable explanation why this solution gives me an error using jtaDataSource?