WebSphere Liberty + Springboot + Hibernate + JNDI
Asked Answered
O

2

6

I am trying to migrate my small application from Tomcat to WebSphere. In order to do so, I am rebuilding it from scratch addressing major components separately. I am struggling with data access / JNDI on webSphere Liberty. I get

javax.naming.NameNotFoundException: javax.naming.NameNotFoundException: java:comp/env/jdbc/test

SERVER.xml

<featureManager>
<feature>webProfile-8.0</feature>
<feature>localConnector-1.0</feature>
<feature>adminCenter-1.0</feature>
<feature>javaee-8.0</feature>
<feature>jndi-1.0</feature>
<feature>concurrent-1.0</feature>

 <dataSource id="test" jndiName="jdbc/test" type="javax.sql.DataSource">
    <jdbcDriver libraryRef="MySQLLib" />
    <properties databaseName="test" serverName="localhost" portNumber="3306" user="user" password="mypassword" />
    <jdbcDriver>
      <library id="MySQLLib">
        <fileset dir="/Library/JDBC/" includes="mysql-connector-java-5.1.14-bin.jar" />
      </library>
    </jdbcDriver>
  </dataSource>

Data config class

@Configuration
public class DataSourceConfig {

@Resource(lookup = "java:comp/env/jdbc/test", name="java:comp/env/jdbc/test")
private DataSource dataSource;

I have also tried this approach :

@Bean
public DataSource dataSource() throws NamingException {
    return (DataSource) new JndiTemplate().lookup("java:comp/env/jdbc/test");
}
Overhang answered 23/9, 2019 at 20:3 Comment(1)
You don't need the DataSourceConfig class. Just specify spring.datasource,jndi-name in your configuration and Spring Boot will do the lookup.Social
B
7

The first thing I notice is that you have 2 <jdbcDriver> elements in your server.xml -- only one should be used, like this:

 <dataSource id="test" jndiName="jdbc/test" type="javax.sql.DataSource">
    <properties databaseName="test" serverName="localhost" portNumber="3306" user="user" password="mypassword" />
    <jdbcDriver>
      <library id="MySQLLib">
        <fileset dir="/Library/JDBC/" includes="mysql-connector-java-5.1.14-bin.jar" />
      </library>
    </jdbcDriver>
  </dataSource>

Next, you are defining a resource reference like this:

@Resource(lookup = "java:comp/env/jdbc/test", name="java:comp/env/jdbc/test")
private DataSource dataSource;

This effectively says "peform a JNDI lookup of 'java:comp/env/jdbc/test' and bind it to the 'java:comp/env/jdbc/test' JNDI name". This would result in an infinite loop or circular reference.

Instead, you want to bind the lookup to the jndiName that you have defined in your server.xml like this:

@Resource(lookup = "jdbc/test", name="java:comp/env/jdbc/test")
private DataSource dataSource;

Or, if that doesn't work you can try a direct lookup the Spring way like this:

@Bean
public DataSource dataSource() throws NamingException {
    return (DataSource) new JndiTemplate().lookup("java:comp/env/jdbc/test");
}

or with Java standard API:

DataSource ds = javax.naming.InitialContext.doLookup("jdbc/test");

If none of these options work, check your server logs for errors or warnings. There ought to be some indication of why the DataSource cannot be created.


New in Liberty 19.0.0.9 -- datasource validation API

In 19.0.0.9 we released a REST API that can be used to validate configuration elements such as dataSources.

To use it with your config, configure an admin user (if you haven't already) like this:

<quickStartSecurity userName="adminuser" userPassword="adminpwd"/>

And then in a web browser go to https://localhost:9443/ibm/api/validation/dataSource/{DATASOURCE_ID} which would be https://localhost:9443/ibm/api/validation/dataSource/test in your case.

To get a full walkthrough of this validation feature, see this post.

Bastian answered 23/9, 2019 at 20:46 Comment(1)
Thank you. This was very helpful. I have moved to 10.0.0.9 and used the utility to confirm my JNDI worked. I still have an issue with data (CrudRepository/JPA with Spring probably) but your answer helped me move forward and confirm that part. I think I will open another question to keep things clear on StackOverflow and avoid confusion for othersOverhang
C
2

This mostly looks correct, except have the lookup match the jndiName that is configured in server.xml,

@Resource(lookup = "jdbc/test", name="java:comp/env/jdbc/test")
private DataSource dataSource;
Cerda answered 23/9, 2019 at 20:47 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.