web-dev-qa-db-ja.com

スタンドアロンJavaプログラムの初期コンテキスト

Tomcat接続プールの作成にJNDIを使用しています。 Webアプリケーションでうまく機能します。 InitialContextはTomcatサーバーによって提供されると考えています。

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

しかし、スタンドアロンのJavaプログラムから同じユーティリティを呼び出そうとすると、initContextオブジェクトはnullです。Contextオブジェクトが期待するすべての必要なプロパティを明示的に提供するにはどうすればよいですか。

エラー:javax.naming.NoInitialContextException:環境またはシステムプロパティで、またはアプレットパラメータとして、またはアプリケーションリソースファイルでクラス名を指定する必要があります:Java.naming.factory.initial

19
Satish Jonnala

独自のカスタムコンテキストを作成することもできます。

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

詳細については、 Application Serverデータソースを使用するローカルでのBeanの実行 を参照してください。


new [〜#〜] update [〜#〜]

クラスを使用できます org.springframework.mock.jndi.SimpleNamingContextBuilder Spring。例えば。:

  • セットアップ:

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

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

以下は、受け入れられた答えから適応した例ですが、余分なクラスを作成しないようにすべてをインラインで実行します。

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();
    }
}
22
Scott Nelson

Tomcat Context Factoryを直接使用する方法はありません。代替に関するもう少しのドキュメントについては here を参照してください。しかし、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);

この外部RegistryContextも使用するようにTomcatのコードを変更すると、両方のセットが同じJNDIプロバイダーを使用することになります。これ 質問 は非常に似ているようです。

1
Elliott Frisch

独自のContextを作成するには、javax.naming.InitialContextをサブクラス化し、メソッドの小さなサブセット(通常はbindおよびlookupメソッド)のみを実装します。

その後、データソースを作成し、それを特定のキーの初期コンテキストにバインドできます。この後、スタンドアロンのJNDIコンテキストの任意の場所からクエリを実行する準備ができましたJavaプログラム。

これは、独自のコンテキストを作成するために使用できるコードです。

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

その後、選択したデータソースを初期化できます。

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

また、コードのどこかで、JNDIコンテキストから既存のデータソースを取得することで使用できます。

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

Tomcatは、InitialContextクラスと連携するContextおよびDataSource実装を提供します。 Tomcatを実行すると、Tomcatの実装を指すようにContext.INITIAL_CONTEXT_FACTORYプロパティが設定されます。 Tomcatを実行していない場合、この機能はありません...接続プーリングにはc3p0などのサードパーティライブラリを使用する必要があります。

0
ClickerMonkey

ブローコードを使用して初期コンテキストを作成できます。

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

カスタム初期コンテキストを作成する場合は、javax.naming.InitailContextクラスを拡張できます

0
faizan saifi