How to configure jndi DataSource in Tomcat 7

随声附和 提交于 2019-12-20 07:57:07

问题


I need to deploy our web application in tomcat 7.but my application use JNDI data source. how to create jndi DataSource in Tomcat 7


回答1:


Have you tried the Tomcat Manual: http://tomcat.apache.org/tomcat-7.0-doc/jndi-datasource-examples-howto.html

(Hint: Google String was "jndi datasource tomcat 7")




回答2:


I can show how I do it in Tomcat 9. This may or may not work in Tomcat 7. FYI, Tomcat 7 seems to be in maintenance-mode.

In my situation, I want to store settings such as database access info outside my web-app’s WAR file. This gives me flexibility for each of my development, testing, and production servers to have their own settings resident in their file system. Ditto for my customers running my app. No need to edit the WAR file, or produce individualized WAR files, if these settings are kept externally, living on each server separately. And no need to re-edit the WAR file when settings change or when a new version of the WAR file arrives.

In the Tomcat "home" folder, or Tomcat "base" folder if you’ve designated one, go into the conf folder to create a Catalina folder. ”Catalina” is the name of the Tomcat engine. Nest within that a new folder named localhost, the name of your host. Within that create an XML file, named the name of your context.

I find that app-name-goes-here.xml approach is a simple place to store these settings external to my web-app’s WAR file, yet not having to mess with Tomcat's own files. This approach is rather obtusely documented in the middle bullet beginning "In individual files" in the Defining a context section of The Context Container page of the Tomcat Configuration Reference.

For example, here is a screenshot of my app named TickTock, using a "base" folder outside the Tomcat folder.

In that XML file you can define things like environment variables such as a "DEV" versus "PROD" flag or a feature toggle, and resources such as a JDBC DataSource singleton to be instantiated. These items are managed by Tomcat's own implementation of an LDAP-like server that can be accessed via JNDI.

Here is a nearly-realistic example of my ticktock.xml file.

Notice the first few attributes of each attribute; these are standard, defined by the Servlet spec and documented here for environment entries, and here for resource entries.

And notice how the Resource element has additional attributes. These are specific the particular resource. In this case, the particular resource is this Postgres JDBC driver.

<Context>

    <!-- Domain: DEV, TEST, PROD -->
    <Environment
            name = "work.basil.ticktock.deployment-mode"
            description = "Signals whether to run this web-app with development, testing, or production settings."
            type = "java.lang.String"
            value = "DEV"
            override = "false"
            />

     <Resource
             name = "jdbc/ticktockdb"
             description = "Database used by the TickTock app."
             type = "javax.sql.DataSource"
             auth = "Container"
             singleton = "true"

             driverClassName = "org.postgresql.Driver"
             url = "jdbc:postgresql://127.0.0.1:5432/ticktockdb"
             username = "TickTockApp"
             password = "pw"
             maxTotal = "20"
             maxIdle = "10"
             maxWaitMillis = "-1"
             />

</Context>

How get an object for either this environment entry or this resource entry?

First, get a JNDI "context" from which to access these entries.

Context ctx = new InitialContext ();

You will also need trap for any NamingException, but I'll omit that code.

You can dump all your environment entries with this simple code. I use lambda syntax here, but you can just as well use classic Java syntax.

// Read all properties.
System.out.println ( "INFO - Dumping bindings for environment variables." );
ctx.listBindings ( "java:comp/env" ).asIterator ().forEachRemaining (
        ( Binding binding ) -> {
            String msg = binding.getName () + " : " + binding.getObject ();
            System.out.println ( msg );
            this.add ( new Paragraph ( msg ) );
        } );

Or fetch a specific one.

String deployMode = ( String ) ctx.lookup( "java:comp/env/work.basil.ticktock.deployment-mode" );

To get a DataSource object, we must cast the Object returned by JNDI.

DataSource ds = ( DataSource ) ctx.lookup( "java:/comp/env/jdbc/ticktockdb" );

This is all we need!

You will see other discussions about additional configuration for further Servlet or Tomcat features that provide another layer of indirection, so the naming within your code does not need to match the names in the LDAP or other server being accessed by JNDI. While I am not sure, I believe that if the extra layer of indirection is not necessary for our web-app project, our environment or resource request will be provided directly from the naming server if we specify the entire JNDI lookup string as seen here, starting with java:/comp/env rather than just the ending part jdbc/ticktockdb. If anyone would like to clarify this, please post a comment or edit this Answer.

JDBC driver

JDBC drivers are problematic in a Servlet container. Long story short, you should not bundle the JDBC driver with your web-app in its WAR file.

Instead, you want to load the JDBC driver on the Common class loader or possibly the Shared class loader. For the Common class loader to auto-detect your JDBC driver, drop its JAR file into Tomcat's lib folder (or if using a designated "base" folder as seen above, create a lib folder as seen above, and deposit your driver’s JAR there).



来源:https://stackoverflow.com/questions/28368103/how-to-configure-jndi-datasource-in-tomcat-7

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!