Java: comp / env / làm gì?


116

Tôi chỉ dành quá nhiều thời gian trong ngày để cố gắng tìm ra một số lỗi khi kết nối một số bean nhà máy JNDI. Vấn đề hóa ra là thay vì ...

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

Tôi đã thực sự viết điều này ...

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

Tôi suy luận rằng java:comp/env/có lẽ tham chiếu một số biến môi trường và làm cho nó để cuối cùng, tệp ngữ cảnh của tôi được xem xét. Sự khác biệt duy nhất là java:comp/env/. Từ miệng của một chuyên gia, điều đó làm gì?

Nếu không có java:comp/env/tiền tố trong giá trị, tôi sẽ gặp lỗi "Tên jdbc không bị ràng buộc trong Ngữ cảnh này" .


3
Cái nào ban đầu bạn sử dụng? Câu hỏi của bạn ngụ ý rằng bạn đã sử dụng sai ví dụ thứ hai ( jdbc/locvà do đó java:comp/env/jdbc/loclà chính xác), trong khi câu trả lời của cherouvim ngụ ý rằng bạn đã sử dụng sai ví dụ đầu tiên ( java:comp/env/jdbc/locvà do đó jdbc/loclà chính xác). Bất kể, câu trả lời thực sự là: nó phụ thuộc vào bối cảnh hiện tại .
BalusC

1
Một cái không hoạt động thực sự đã thiếu java: comp / env / jdbc / loc, như ngụ ý. Tệp ngữ cảnh được chỉ ra bao gồm tài nguyên "loc". Các khả năng cho bối cảnh "hiện tại" là gì?
Danny

Câu trả lời:


100

Trích dẫn https://web.archive.org/web/20140227201242/http://v1.dione.zcu.cz/java/docs/jndi-1.2/tutorial/beyond/misc/policy.html

Trong bối cảnh gốc của không gian tên là một ràng buộc với tên "comp", được liên kết với một cây con dành riêng cho các ràng buộc liên quan đến thành phần. Tên "comp" là viết tắt của thành phần. Không có ràng buộc khác ở bối cảnh gốc. Tuy nhiên, bối cảnh gốc được dành riêng cho việc mở rộng chính sách trong tương lai, cụ thể là đặt tên các tài nguyên được gắn không phải với chính thành phần mà cho các loại thực thể khác như người dùng hoặc phòng ban. Ví dụ: các chính sách trong tương lai có thể cho phép bạn đặt tên người dùng và tổ chức / phòng ban bằng cách sử dụng các tên như "java: user / alice" và "java: org / Engineering".

Trong ngữ cảnh "comp", có hai ràng buộc: "env" và "UserTransaction". Tên "env" được liên kết với một cây con được dành riêng cho các ràng buộc liên quan đến môi trường của thành phần, như được định nghĩa bởi bộ mô tả triển khai của nó. "Env" là viết tắt của môi trường. J2EE khuyến nghị (nhưng không yêu cầu) cấu trúc sau cho không gian tên "env".

Vì vậy, ràng buộc bạn đã làm từ mùa xuân hoặc, ví dụ, từ một mô tả bối cảnh tomcat đi theo mặc định theo java: comp / env /

Ví dụ: nếu cấu hình của bạn là:

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

Sau đó, bạn có thể truy cập trực tiếp bằng cách sử dụng:

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

hoặc bạn có thể thực hiện một bước trung gian để bạn không phải chỉ định "java: comp / env" cho mỗi tài nguyên bạn truy xuất:

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

Tôi nghĩ rằng tôi đã hiểu điều này một cách chính xác, nhưng những bình luận thêm khiến tôi nhận ra mình đã làm quá lạc hậu. Nếu bộ mô tả bối cảnh tomcat đi, theo mặc định, theo java: comp / env, điều đó có nghĩa là tôi có thể bỏ qua java: comp / env từ giá trị không? Trong trường hợp của tôi, tôi đã phải thêm nó để làm cho lỗi "Tên jdbc không bị ràng buộc trong Ngữ cảnh này" biến mất.
Danny

4
Bạn liên kết bằng cách sử dụng "foo" và tra cứu bằng "java: comp / env / foo". Có một cái nhìn tại blog.cherouvim.com/javax-sql-datasource-exposed-through-jndi
cherouvim

3
Liên kết trên là từ hướng dẫn JNDI độc lập, ban đầu có sẵn trên: docs.oracle.com/javase/jndi/tutorial/beyond/misc/policy.html .
Danilo Piazzalunga

Điều gì nếu có nhiều / -es trong tra cứu của bạn? Giống như: "java: com / env / foo / bar", giá trị jndiName của bạn là "foo / bar" hay "foo.bar"?
Pieter De Bie

Giá trị jndiName chính xác sẽ "foo / bar" @PieterDeBrie.
tftdias

37

Ngoài ra còn có một resourceRefthuộc tính JndiObjectFactoryBeanđó là, khi được đặt thành true, được sử dụng để tự động thêm vào chuỗi java:comp/env/nếu nó chưa xuất hiện.

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

3

Sau nhiều lần thử và đi sâu vào mã nguồn của Tomcat, tôi phát hiện ra rằng thuộc tính đơn giản useNaming = "false" đã lừa được !! Bây giờ Tomcat giải quyết tên java: / liferay thay vì java: comp / env / liferay


Bạn có thể cung cấp một ví dụ đầy đủ, bao gồm cả định nghĩa tài nguyên? Tôi đã không quản lý để thiết lập thành công với Tomcat 8.5 - một ví dụ toàn diện hơn sẽ giúp tôi thấy lỗi của mình, có thể.
RobertG
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.