Initialcontext dans un programme Java autonome
j'utilise un JNDI pour créer un pool de connexion tomcat. Il fonctionne très bien dans une application web. Je crois que le Contexteinitial est fourni par le serveur tomcat.
Context initContext = new InitialContext();
Context envContext = (Context)initContext.lookup("java:/comp/env");
dataSource = (DataSource)envContext.lookup("jdbc/testdb");
Mais quand j'essaie d'appeler le même utilitaire à partir d'un programme Java autonome, l'objet initContext est null. Comment puis-je fournir explicitement toutes les propriétés nécessaires que L'objet contextuel attend.
erreur: javax.nommer.NoInitialContextException: besoin de spécifier la classe nom de environnement ou propriété du système, ou comme paramètre applet, ou dans un fichier de ressources d'application: java.nommer.usine.initiale
5 réponses
Vous pouvez aussi créer votre propre contexte.
LocalContext ctx = LocalContextFactory.createLocalContext();
ctx.addDataSource("jdbc/testdb", driverName, url, usr, pwd);
Voir lancer des haricots localement qui utilisent les sources de données du serveur D'Application pour plus de détails.
UPDATE
Vous pouvez utiliser la classe org.springframework.mock.jndi.SimpleNamingContextBuilder
de Printemps. par exemple:
Installation:
SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder(); builder.bind("jdbc/Oracle", ods); builder.activate();
Utilisation:
DataSource ds = InitialContext.doLookup("jdbc/Oracle");
voici un exemple adapté de la réponse acceptée mais faisant tout en ligne pour éviter de créer des classes supplémentaires.
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();
}
}
Il n'y a pas moyen d'utiliser directement L'usine de contexte Tomcat, voir ici pour un peu plus de documentation sur les alternatives. Mais je vous recommande d'essayer de gérer un registre en dehors 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);
Vous pouvez changer votre code dans Tomcat pour utiliser aussi ce RegistryContext externe et ensuite les deux ensembles utiliseraient le même fournisseur JNDI. Ce question semble très similaire.
Tomcat fournit des implémentations de Context & DataSource qui fonctionnent avec la classe InitialContext. Lors de L'exécution de Tomcat le contexte.La propriété INITIAL_CONTEXT_FACTORY est définie pour pointer vers les implémentations de Tomcat. Quand vous n'utilisez pas Tomcat, vous n'avez pas cette capacité... vous devez utiliser une bibliothèque tierce comme c3p0 pour la mise en commun des connexions.
Vous pouvez créer un contexte initial en utilisant le code blow.
InitialContext ic = new InitialContext();
// Retrieve the Home interface using JNDI lookup
Object helloObject = ic.lookup("java:comp/env/ejb/HelloBean");
si vous voulez créer un contexte initial personnalisé, vous pouvez étendre javax.nommer.Initailcontext class