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

19
demandé sur Zong 2013-12-03 23:03:33

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.


new 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");
    
6
répondu Paul Vargas 2016-07-08 16:18:08

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();
    }
}
21
répondu Scott Nelson 2014-02-12 16:35:55

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.

1
répondu Elliott Frisch 2017-05-23 12:31:59

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.

0
répondu ClickerMonkey 2013-12-03 19:10:41

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

0
répondu faizan saifi 2018-08-31 13:38:46