Apa yang dimaksud dengan java: comp / env / do?

116

Saya hanya menghabiskan terlalu banyak waktu hari saya mencoba mencari tahu beberapa kesalahan saat menghubungkan beberapa biji pabrik JNDI. Masalahnya ternyata bukan ini ...

<bean id="someId" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="java:comp/env/jdbc/loc"/>
</bean>

Saya sebenarnya telah menulis ini ...

<bean id="someId" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="jdbc/loc"/>
</bean>

Saya menyimpulkan bahwa java:comp/env/mungkin mereferensikan beberapa variabel lingkungan dan membuatnya sehingga, pada akhirnya, file konteks saya dilihat. Satu-satunya perbedaan adalah java:comp/env/. Dari mulut seorang ahli, apa fungsinya?

Tanpa java:comp/env/awalan dalam nilai, saya akan mendapatkan kesalahan yang mengatakan "Nama jdbc tidak terikat dalam Konteks ini" .

Danny
sumber
3
Yang mana yang pertama kali Anda gunakan? Pertanyaan Anda menyiratkan bahwa Anda salah menggunakan contoh kedua ( jdbc/locdan karenanya java:comp/env/jdbc/locbenar), sedangkan jawaban cherouvim menyiratkan bahwa Anda salah menggunakan contoh pertama ( java:comp/env/jdbc/locdan dengan demikian jdbc/locbenar). Terlepas dari itu, jawaban sebenarnya adalah: itu tergantung pada konteks saat ini .
BalusC
1
Yang tidak berhasil memang kehilangan java: comp / env / jdbc / loc, seperti yang tersirat. File konteks yang ditunjuk untuk menyertakan sumber daya "loc". Apa kemungkinan untuk konteks "saat ini"?
Danny

Jawaban:

100

Mengutip https://web.archive.org/web/20140227201242/http://v1.dione.zcu.cz/java/docs/jndi-1.2/tutorial/beyond/misc/policy.html

Pada konteks root namespace adalah binding dengan nama "comp", yang terikat ke subpohon yang disediakan untuk binding terkait komponen. Nama "comp" adalah singkatan dari komponen. Tidak ada binding lain di konteks root. Namun, konteks akar dicadangkan untuk perluasan kebijakan di masa mendatang, khususnya untuk menamai sumber daya yang tidak terikat pada komponen itu sendiri, tetapi untuk jenis entitas lain seperti pengguna atau departemen. Misalnya, kebijakan di masa mendatang mungkin memungkinkan Anda memberi nama pengguna dan organisasi / departemen dengan menggunakan nama seperti "java: user / alice" dan "java: org / engineering".

Dalam konteks "comp", ada dua binding: "env" dan "UserTransaction". Nama "env" terikat ke subpohon yang dicadangkan untuk binding terkait lingkungan komponen, seperti yang ditentukan oleh deskriptor penerapannya. "env" adalah kependekan dari lingkungan. J2EE merekomendasikan (tetapi tidak memerlukan) struktur berikut untuk namespace "env".

Jadi, pengikatan yang Anda lakukan dari spring atau, misalnya, dari deskripsi konteks kucing jantan, buka secara default di java: comp / env /

Misalnya, jika konfigurasi Anda adalah:

<bean id="someId" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="foo"/>
</bean>

Kemudian Anda dapat mengaksesnya secara langsung menggunakan:

Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:comp/env/foo");

atau Anda dapat membuat langkah perantara sehingga Anda tidak perlu menentukan "java: comp / env" untuk setiap sumber daya yang Anda ambil:

Context ctx = new InitialContext();
Context envCtx = (Context)ctx.lookup("java:comp/env");
DataSource ds = (DataSource)envCtx.lookup("foo");
cherouvim
sumber
Saya pikir saya telah memahami ini dengan benar, tetapi komentar lebih lanjut membuat saya menyadari bahwa saya telah melakukannya secara terbelakang. Jika deskripsi konteks kucing jantan pergi, secara default, di bawah java: comp / env, bukankah itu berarti bahwa saya dapat menghilangkan java: comp / env dari nilainya? Dalam kasus saya, saya harus menambahkannya untuk menghilangkan kesalahan "Nama jdbc tidak terikat dalam Konteks ini".
Danny
4
Anda mengikat menggunakan "foo" dan mencari menggunakan "java: comp / env / foo". Silahkan lihat pada blog.cherouvim.com/javax-sql-datasource-exposed-through-jndi
cherouvim
3
Tautan di atas adalah dari tutorial JNDI mandiri, aslinya tersedia di: docs.oracle.com/javase/jndi/tutorial/beyond/misc/policy.html .
Danilo Piazzalunga
bagaimana jika ada lebih banyak / -es dalam pencarian Anda? Seperti: "java: com / env / foo / bar", apakah nilai jndiName Anda "foo / bar" atau "foo.bar"?
Pieter De Bie
Nilai jndiName yang benar adalah "foo / bar" @PieterDeBrie.
tftdias
37

Ada juga sebuah properti resourceRefdari JndiObjectFactoryBeanyang, ketika diatur ke true, digunakan untuk secara otomatis tambahkan string java:comp/env/jika tidak sudah ada.

<bean id="someId" class="org.springframework.jndi.JndiObjectFactoryBean">
  <property name="jndiName" value="jdbc/loc"/>
  <property name="resourceRef" value="true"/>
</bean>
Filip Spiridonov
sumber
3

Setelah beberapa kali mencoba dan mendalami kode sumber Tomcat, saya menemukan bahwa properti sederhana useNaming = "false" berhasil !! Sekarang Tomcat menyelesaikan nama java: / liferay alih-alih java: comp / env / liferay

Thiago Leão Moreira
sumber
Bisakah Anda memberikan contoh lengkap, termasuk definisi sumber daya? Saya tidak berhasil mengatur ini dengan sukses dengan Tomcat 8.5 - contoh yang lebih komprehensif akan membantu saya melihat kesalahan saya, mungkin.
RobertG