2013-12-03 33 views
18

Tomcat bağlantı havuzu oluşturmak için JNDI kullanıyorum. Bir web uygulamasında harika çalışıyor. InitialContext'in tomcat sunucusu tarafından sağlandığını düşünüyorum.Tek başına bir Java programında Initialcontext

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

Ama tek başına bir Java programından aynı faydayı aramaya çalıştığınızda, initContext nesnesi boş. Context nesnesinin beklediği tüm gerekli özellikleri nasıl açıkça sağlayabilirim.

Hata: javax.naming.NoInitialContextException: çevre ya da sistem özelliğinde sınıf adını belirtin veya Need bir uygulama kaynak dosyasında bir uygulama parametresi veya olarak: java.naming.factory.initial

cevap

5

Ayrıca kendi özel bağlamınızı da oluşturabilirsiniz.

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

Daha fazla bilgi için bkz. Running Beans Locally that use Application Server Data Sources.


newGÜNCELLEME

Sen Bahar sınıfını org.springframework.mock.jndi.SimpleNamingContextBuilder kullanabilirsiniz. örneğin:

  • Kurulumu:

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

    İşte
    DataSource ds = InitialContext.doLookup("jdbc/Oracle"); 
    
+0

Bağlı makalenin son yorumlar çözümleri arabası olduğunu belirtti olarak, unutmayın: adı boş ya da ben ekledim ... – Lonzak

+0

Hey @Lonzak bulunmazsa eğer bir StackOverflowException araması sırasında atılır bir güncelleme. –

0

Tomcat, InitialContext sınıfıyla birlikte çalışan İçerik & DataSource uygulamalarını sağlar. Tomcat'i çalıştırırken Context.INITIAL_CONTEXT_FACTORY özelliği, Tomcat'in uygulamalarına işaret edecek şekilde ayarlanmıştır. Tomcat'i çalıştırmamanız durumunda, bu yeteneğe sahip değilsiniz ... bağlantı havuzu için c3p0 gibi bir üçüncü taraf kitaplığı kullanmanız gerekir.

1

Tomcat Bağlam Fabrikasını doğrudan kullanmanın bir yolu yok, alternatifler hakkında daha fazla bilgi için bkz. here. Ama

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

Ayrıca aynı Jndi sağlayıcısını kullanarak olurdu o zaman bu dış RegistryContext ve set (ler) her ikisini de kullanmak Tomcat kodunuzu değiştirebilir ... Tomcat dışında bir kayıt çalıştırmayı deneyin öneriyoruz. Bu question çok benzer görünüyor.

17

kabul edilen yanıt uyarlanan ama önlemek için satır içi her şeyi yapıyor bir örnektir ekstra sınıflar oluşturmak.

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(); 
    } 
} 
+3

Tebrikler! En uygun çözüm, temiz ve basit! –

+2

Mükemmel bir inline çözüm için bir vuru :-) – janhink

+2

Bu, Java'nın arcane API'lerini kullanarak saatlerimi kurtardı. Teşekkür ederim! –

İlgili konular