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.