Quarkus How to Specify JNDI Datasources

Viewed 1648

I am evaluating Quakus as a replacement for a Tomcat environment. I understand the challenges of what I am trying to do, but I first need to validate my existing, legacy JSP application will work using Quarkus. I am using quarkus.undertow as my servlet container.

I've overcome several obstacles thus far. The one I am running into now is how to use my data sources.

Currently, our data sources are set in Tomcat's server.xml as GlobalNamingResources and binding them in the web app's META-INF/context.xml as ResourceLinks.

I've transferred the data source setting to Quarkus' application.properties as such:

quarkus.datasource.menudb.url=jdbc:mysql://some.server.url/menuadmin
quarkus.datasource.menudb.driver=com.mysql.cj.jdbc.Driver
quarkus.datasource.menudb.username=web
quarkus.datasource.menudb.password=<password>

which I understand, from the documentation, is the way to do it. But, the documentation then shows injecting the datasource:

@Inject
@DataSource("users")
AgroalDataSource dataSource1;

In my case, i would replace users with my data source name menudb in the annotation. However, I have data access classes I need to be able to reuse that create the InitialContext, lookup the data source using the JNDI resource name passed in, and creates the data source:

InitialContext ic = new InitialContext();
DataSource ds = (DataSource)ic.lookup("java:comp/env/<jndi name>");
conn = ds.getConnection();

This is causing the following error:

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
    at javax.naming.spi.NamingManager.getInitialContext(NamingManager.java:662)
    at javax.naming.InitialContext.getDefaultInitCtx(InitialContext.java:313)
    at javax.naming.InitialContext.getURLOrDefaultInitCtx(InitialContext.java:350)
    at javax.naming.InitialContext.lookup(InitialContext.java:417)
    at com.gy.obj.ContextManager.contextInitialized(ContextManager.java:367)
    at io.undertow.servlet.core.ApplicationListeners.contextInitialized(ApplicationListeners.java:188)
...

Initial research has lead me to Apache Camel, but that, at first glance, does not seem to be an appropriate solution. I've also read about setting a jndi.properties as so:

# Needed env settings for JNDI.
java.naming.factory.initial=<Some JNDI Service Provider Name>

But I am not certain which provider to use and as of now can't seem to locate documentation on the various providers.

My question is, am I at least on the right track and what provider would I use? I would really not like to touch my existing data access classes to provide injection, if I do not have too. However, I would not be opposed to such as what we currently have configured works for Tomcat.

1 Answers

JNDI is intentionally not supported, as we consider it an unnecessary complexity which is not useful in the Quarkus model: there are no runtime deployments and all code is known at build time so there's no need for such decoupling.

The solution is simple: just adapt the code to not look it up from the JDNI context but look it up from the CDI bean manager.

While we're able to support most high level APIs, it should be easy to port existing applications but don't assume that all legacy technologies will be provided - it's a good time to get rid of some and move on.

That said I supposed JNDI could easily be emulated, but so far we'd prefer to avoid that; feel free to open an issue if this is very important to you.

Related