5 votes

Comment utiliser une ressource JNDI dans une application JAX-RS (Jersey) ?

J'essaie d'établir une connexion à ma base de données par le biais d'une ressource JNDI Tomcat. J'ai consulté de nombreux articles aujourd'hui et je n'arrive pas à trouver de réponse.

Dans mon server.xml, j'ai :

  <GlobalNamingResources>
  <Resource name="jdbc/MyDB" auth="Container" type="javax.sql.DataSource"
      maxActive="100" maxIdle="30" maxWait="10000"
      username="tomcat" password="...."
      driverClassName="com.mysql.jdbc.Driver"
      url="jdbc:mysql://localhost:3333/tomcat?autoReconnect=true"/>

  .....
  </GlobalNamingResources>

Dans mon service web, je tente d'accéder à la ressource avec :

    InitialContext ctx = new InitialContext();
    DataSource data = (DataSource)ctx.lookup("java:comp/env/jdbc/MyDB");
    Connection conn = data.getConnection();

Lorsque j'exécute le code, j'obtiens cette exception :

Nov 2, 2011 1:06:20 PM com.sun.jersey.spi.container.ContainerResponse  mapMappableContainerException
SEVERE: The exception contained within MappableContainerException could not be mapped to a response, re-throwing to the HTTP container
javax.naming.NameNotFoundException: Name jdbc is not bound in this Context
...

J'ai le plus récent mysql-connector-java-5.1.18-bin.jar dans la librairie de ma web-app et dans celle de mon tomcat.

Pouvez-vous m'aider à le faire fonctionner ?

1voto

J'utilise ce code, avec seulement le nom de la ressource, et cela fonctionne :

private Connection getConnection(){
      final Context ctx = new InitialContext();
      final DataSource ds = (DataSource) ctx.lookup("jdbc/MyDB");
      if (ds != null)
      {
             return ds.getConnection();
      }
      else
      {

      }
}

0voto

Irshad Points 318

Nous devons juste mentionner le nom jndi après java : Dans votre cas :

InitialContext ctx = new InitialContext();
DataSource data = (DataSource)ctx.lookup("java:/jdbc/MyDB");
Connection conn = data.getConnection();

Parce que vous avez configuré dans votre server.xml comme ci-dessous :

<GlobalNamingResources>
  <Resource name="jdbc/MyDB" auth="Container" type="javax.sql.DataSource"
      maxActive="100" maxIdle="30" maxWait="10000"
      username="tomcat" password="...."
      driverClassName="com.mysql.jdbc.Driver"
      url="jdbc:mysql://localhost:3333/tomcat?autoReconnect=true"/>

  .....
  </GlobalNamingResources>

0voto

Blaskovicz Points 1171

Ma solution a été de passer à un fichier de propriétés pour les informations de la base de données, puis de l'utiliser avec le gestionnaire d'entités.

import java.io.FileReader;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.servlet.ServletException;

import org.eclipse.persistence.config.EntityManagerProperties;
import org.eclipse.persistence.config.PersistenceUnitProperties;

...

        Properties properties = new Properties();
        FileReader fr = new FileReader(Constants.Config.getPropertiesFile());
        properties.load(fr);

        // connect to the database
        Map<String,String> emMap = new HashMap<String,String>();
        emMap.put(PersistenceUnitProperties.APP_LOCATION, Constants.Config.getAppDir());        
        emMap.put(EntityManagerProperties.JDBC_USER, properties.getProperty("db.username"));
        emMap.put(EntityManagerProperties.JDBC_PASSWORD, properties.getProperty("db.password"));
        // iterate over these properties attempting to read them in and connect to the url
        List<?> dbProps = Collections.list(properties.keys());
        Collections.sort(dbProps, new Comparator<Object>() {
            @Override
            public int compare(Object o1, Object o2) {
                return o1.toString().compareTo(((String)o2));
            }
        });

        for(Object propKey : dbProps){
            // support multiple database key/values in the eform db.url, db.url1, ...  db.urlN
            if(!propKey.toString().matches("db.url\\d*")){
                continue;
            }
            String dbLocation = properties.getProperty(propKey.toString());
            try {
                if(dbLocation == null) continue;

                emMap.put(EntityManagerProperties.JDBC_URL, dbLocation);
                EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("db", emMap);
                em = entityManagerFactory.createEntityManager();
                // ensure we're connected by executing a no-op query
                em.createNativeQuery("select current_database()").getSingleResult(); // will only work for postgresql
                properties.put("db.connected", dbLocation);
                break;
              }
              catch (javax.persistence.PersistenceException e) {
                Utility.logger(DataHolder.class).error("Couldn't connect to " + dbLocation);
              }
        }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X