it-swarm.com.de

Anfangskontext in einem eigenständigen Java-Programm

Ich verwende eine JNDI zum Erstellen eines Tomcat-Verbindungspools. Es funktioniert gut in einer Webanwendung. Ich glaube, der InitialContext wird vom Tomcat-Server bereitgestellt.

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

Wenn ich jedoch versuche, dasselbe Dienstprogramm von einem eigenständigen Java-Programm aufzurufen, ist das Objekt initContext null. Wie kann ich explizit alle erforderlichen Eigenschaften angeben, die das Context-Objekt erwartet.

Fehler: javax.naming.NoInitialContextException: Die Klasse muss angegeben werden Name in der Umgebung oder Systemeigenschaft oder als Applet-Parameter oder in einer Anwendungsressourcendatei: Java.naming.factory.initial

19
Satish Jonnala

Sie können auch Ihren eigenen benutzerdefinierten Kontext erstellen. 

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

Siehe Beans lokal ausführen, die Anwendungsserver-Datenquellen verwenden für weitere Details.


new UPDATE

Sie können die Klasse org.springframework.mock.jndi.SimpleNamingContextBuilder von Spring verwenden. z.B.:

  • Konfiguration:

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

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

Hier ist ein Beispiel, das sich aus der akzeptierten Antwort anpasst, jedoch alles inline macht, um das Erstellen zusätzlicher Klassen zu vermeiden.

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
Scott Nelson

Es gibt keine Möglichkeit, die Tomcat Context Factory direkt zu verwenden. Weitere Informationen zu den Alternativen finden Sie in here . Ich empfehle Ihnen jedoch, eine Registry außerhalb von Tomcat auszuführen ...

// 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);

Sie können Ihren Code in Tomcat so ändern, dass er auch diesen externen RegistryContext verwendet, und dann würden beide Sets denselben JNDI-Provider verwenden. Diese Frage scheint sehr ähnlich zu sein.

1
Elliott Frisch

Sie können Ihr eigenes Context erstellen, indem Sie javax.naming.InitialContext Unterklassifizieren und nur eine kleine Untergruppe von Methoden implementieren, normalerweise die Methoden bind und lookup.

Anschließend können Sie Ihre Datenquelle erstellen und sie an Ihren ursprünglichen Kontext an einen bestimmten Schlüssel binden. Danach können Sie von jedem Ort aus Ihren JNDI-Kontext in Ihrem eigenständigen Java Programm abfragen.

Mit diesem Code können Sie Ihren eigenen Kontext erstellen:

InitialContext initialContext = new InitialContext() {

    private Map<String, Object> table = new HashMap<>();

    public void bind(String key, Object value) {
        table.put(key, value);
    }

    public Object lookup(String key) throws NamingException {
        return table.get(key);
    }
};

// Activate the initial context
NamingManager.setInitialContextFactoryBuilder(environment -> environment1 -> initialContext);

Dann können Sie Ihre Datenquelle initialisieren, je nachdem, was Sie wählen:

InitialContext ic = new InitialContext();

BasicDataSource bds = new BasicDataSource();
bds.setDriverClassName("com.Microsoft.sqlserver.jdbc.SQLServerDriver");
bds.setUrl(url);
bds.setUsername(username);
bds.setPassword(password);

ic.bind(jndiPath, bds);

An einer anderen Stelle in Ihrem Code können Sie die vorhandene Datenquelle verwenden, indem Sie sie aus dem JNDI-Kontext abrufen:

InitialContext ic2 = new InitialContext();
DataSource ds = (DataSource) ic2.lookup(jndiPath);
assertNotNull(ds);
Connection conn = ds.getConnection();
assertNotNull(conn);
conn.close();
0
gil.fernandes

Tomcat bietet Context- und DataSource-Implementierungen an, die mit der InitialContext-Klasse funktionieren. Bei der Ausführung von Tomcat verweist die Context.INITIAL_CONTEXT_FACTORY-Eigenschaft auf die Tomcat-Implementierungen. Wenn Sie Tomcat nicht ausführen, verfügen Sie nicht über diese Fähigkeit ... Sie müssen eine Drittanbieter-Bibliothek wie c3p0 für das Verbindungs-Pooling verwenden.

0
ClickerMonkey

Sie können einen Anfangskontext mithilfe von Blow-Code erstellen.

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

wenn Sie einen benutzerdefinierten Anfangskontext erstellen möchten, können Sie die Klasse javax.naming.InitailContext erweitern

0
faizan saifi