mkirouac
mkirouac

Reputation: 123

WebSphere Liberty + Springboot + Hibernate + JNDI

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");
}

Upvotes: 6

Views: 2626

Answers (2)

Andy Guibert
Andy Guibert

Reputation: 42926

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.

Upvotes: 7

njr
njr

Reputation: 3484

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;

Upvotes: 2

Related Questions