studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones java java-ee tomcat jndi connection-pooling

programacion - Contexto inicial en un programa Java independiente



manual de programacion android pdf (5)

Estoy usando un JNDI para crear la agrupación de conexiones tomcat. Funciona muy bien en una aplicación web. Creo que el servidor Tomcat proporciona el InitialContext.

Context initContext = new InitialContext(); Context envContext = (Context)initContext.lookup("java:/comp/env"); dataSource = (DataSource)envContext.lookup("jdbc/testdb");

Pero cuando trato de llamar a la misma utilidad desde un programa Java independiente, el objeto initContext es nulo. ¿Cómo puedo proporcionar explícitamente todas las propiedades necesarias que espera el objeto de contexto?

Error: javax.naming.NoInitialContextException: necesita especificar el nombre de la clase en el entorno o propiedad del sistema, o como un parámetro de applet, o en un archivo de recursos de aplicación: java.naming.factory.initial


Aquí hay un ejemplo adaptado de la respuesta aceptada pero haciendo todo en línea para evitar la creación de clases adicionales.

public static void main(String[] args) { setupInitialContext(); //do something that looks up a datasource } private static void setupInitialContext() { try { NamingManager.setInitialContextFactoryBuilder(new InitialContextFactoryBuilder() { @Override public InitialContextFactory createInitialContextFactory(Hashtable<?, ?> environment) throws NamingException { return new InitialContextFactory() { @Override public Context getInitialContext(Hashtable<?, ?> environment) throws NamingException { return new InitialContext(){ private Hashtable<String, DataSource> dataSources = new Hashtable<>(); @Override public Object lookup(String name) throws NamingException { if (dataSources.isEmpty()) { //init datasources MysqlConnectionPoolDataSource ds = new MysqlConnectionPoolDataSource(); ds.setURL("jdbc:mysql://localhost:3306/mydb"); ds.setUser("mydbuser"); ds.setPassword("mydbpass"); dataSources.put("jdbc/mydbname", ds); //add more datasources to the list as necessary } if (dataSources.containsKey(name)) { return dataSources.get(name); } throw new NamingException("Unable to find datasource: "+name); } }; } }; } }); } catch (NamingException ne) { ne.printStackTrace(); } }


No hay una manera de utilizar directamente la fábrica de contexto de Tomcat, consulte here para obtener un poco más de documentación sobre las alternativas. Pero te recomiendo que intentes ejecutar un registro fuera de Tomcat ...

// select the registry context factory for creating a context env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.rmi.registry.RegistryContextFactory"); // specify where that factory is running. env.put(Context.PROVIDER_URL, "rmi://server:1099"); // create an initial context that accesses the registry Context ctx = new InitialContext(env);

Podría cambiar su código en Tomcat para usar también este RegistryContext externo y luego ambos conjuntos usarían el mismo proveedor JNDI. Esta question parece muy similar.


Puedes crear un contexto inicial usando código de golpe.

InitialContext ic = new InitialContext(); // Retrieve the Home interface using JNDI lookup Object helloObject = ic.lookup("java:comp/env/ejb/HelloBean");

Si desea crear un contexto inicial personalizado, puede extender la clase javax.naming.InitailContext


También puedes crear tu propio contexto personalizado.

LocalContext ctx = LocalContextFactory.createLocalContext(); ctx.addDataSource("jdbc/testdb", driverName, url, usr, pwd);

Consulte Ejecución de Beans localmente que utiliza orígenes de datos del servidor de aplicaciones para obtener más detalles.

ACTUALIZAR

Puede usar la clase org.springframework.mock.jndi.SimpleNamingContextBuilder de Spring. p.ej:

  • Preparar:

    SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder(); builder.bind("jdbc/Oracle", ods); builder.activate();

  • Utilizar:

    DataSource ds = InitialContext.doLookup("jdbc/Oracle");


Tomcat proporciona implementaciones Context & DataSource que funcionan con la clase InitialContext. Al ejecutar Tomcat, la propiedad Context.INITIAL_CONTEXT_FACTORY se establece para que apunte a las implementaciones de Tomcat. Cuando no está ejecutando Tomcat, no tiene esta capacidad ... necesita usar una biblioteca de terceros como c3p0 para la agrupación de conexiones.