2013-01-31 22 views
6

Đây là câu hỏi đầu tiên của tôi trong Stack Overflow vì vậy tôi hy vọng nó sẽ không quá đơn giản. Tôi đã tìm kiếm trên Internet cho một giải pháp tốt nhưng bây giờ tôi không có nó.Cách dễ dàng để truy cập vào một ejb từ xa nằm trong một máy chủ khác

Tôi là một người rất ăn xin với EJB, JNDI và Java EE nói chung, nhưng vào những tháng cuối cùng tôi đã có thể làm một số điều có thể chấp nhận được trong môi trường này. Bây giờ tôi đang tập trung một vấn đề tại nơi làm việc và bây giờ giải pháp không tốt như tôi muốn.

Kịch bản này là: Tôi có ứng dụng EAR chạy trong Glassfih 3.1.2. Tôi đã tuyên bố EJB trong ứng dụng EAR này với các hạt không quốc tịch cung cấp các phương thức thông qua Giao diện từ xa.

Đây là Bean từ xa của tôi chạy trong một máy chủ gọi là server1, ví dụ

package com.booreg; 

import javax.ejb.LocalBean; 
import javax.ejb.Stateless; 

import com.booreg.IMyRemoteBean; 

@Stateless 
@LocalBean 
public class MyRemoteBean implements IMyRemoteBean 
{ 
    @Override 
    public String helloWorld() 
    { 
     return "Hi what's up boy"; 
    } 
} 

Đây là giao diện cho nó

package com.booreg; 

import javax.ejb.Remote; 

@Remote 
public interface IMyRemoteBean 
{ 
    public String helloWorld(); 
} 

Sau đó, tôi có một ứng dụng EAR thứ hai mà phải chạy phải nhất thiết trên một máy chủ khác, được gọi là server2. APP thứ hai đang sử dụng JSF và Managed Beans. Chúng tôi đã một Bean Managed đóng vai trò như một khách hàng từ xa của MyRemoteBeanRemote, như thế này:

package com.nucleus; 

import javax.ejb.EJB; 
import javax.faces.bean.ManagedBean; 
import javax.faces.bean.ViewScoped; 

import com.booreg.IMyRemoteBean; 

@ManagedBean 
@ViewScoped 
public class MyManagedBean 
{ 
    @EJB(name="TheRef") IMyRemoteBean myRemoteBean; 

    public String getPhrase() { return myRemoteBean.helloWorld(); } 
} 

Tôi đã đến đến điểm mà các công trình này tuyên bố một tập tin/CN-web.xml ejb-ref bên trong WEB-INF trong dự án web của tôi.

<ejb-ref> 
    <ejb-ref-name>TheRef</ejb-ref-name> 
    <jndi-name>corbaname:iiop:server1:3700#java:global/booreg/booreg.ejb/MyRemoteBean!com.booreg.IMyRemoteBean</jndi-name> 
</ejb-ref> 

Tôi hiểu rằng với tập tin sun-web.xml này jndi tên làm cho các ứng dụng thứ hai để biết được nơi để xác định vị trí việc thực hiện ejb nằm ở ứng dụng đầu tiên. Nhưng ở đây tôi có một số câu hỏi:

  1. Cần khai báo một mục nhập ejb-ref cho mỗi giao diện EJB mà tôi có trong dự án của mình?
  2. Làm cách nào để tránh tạo tham chiếu tĩnh tới máy chủ/cổng (server1: 3700 trong khi phát triển) bên trong tệp sun-web.xml? Khi điều này sẽ đi vào sản xuất tôi sẽ phải thay đổi bằng tay tên sever cho mỗi ?? Điều này nghe có vẻ kì quái. Tôi có thể sử dụng một số loại biến ở phía máy chủ để chỉ định máy chủ/cổng không?

Tôi hy vọng tôi đã giải thích cho bản thân mình đủ tốt.

Rất cám ơn

Cập nhật: cuối cùng, nhờ link này, tôi thấy rằng có thể làm tài liệu tham khảo đến máy chủ ejb (server1) tạo ra một tập tin jndi.properties bên trong classpath của tôi. Tệp này phải chứa các dòng như thế này.

java.naming.factory.initial=com.sun.enterprise.naming.SerialInitContextFactory 
java.naming.factory.url.pkgs=com.sun.enterprise.naming 
java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl 
org.omg.CORBA.ORBInitialHost=server1 
org.omg.CORBA.ORBInitialPort=3700 

Nhưng tôi vẫn gặp sự cố. Khi triển khai ứng dụng xuất hiện ngoại lệ tiếp theo tại server1, tôi không thể triển khai ứng dụng.

ADVERTENCIA: IOP00100006: Class com.sun.jersey.server.impl.cdi.CDIExtension is not Serializable 
org.omg.CORBA.BAD_PARAM: ADVERTENCIA: IOP00100006: Class com.sun.jersey.server.impl.cdi.CDIExtension is not Serializable vmcid: SUN minor code: 6 completed: Maybe 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39) 
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513) 
    at com.sun.corba.ee.spi.orbutil.logex.corba.CorbaExtension.makeException(CorbaExtension.java:248) 
    at com.sun.corba.ee.spi.orbutil.logex.corba.CorbaExtension.makeException(CorbaExtension.java:95) 
    at com.sun.corba.ee.spi.orbutil.logex.WrapperGenerator.handleFullLogging(WrapperGenerator.java:387) 
    at com.sun.corba.ee.spi.orbutil.logex.WrapperGenerator.access$400(WrapperGenerator.java:107) 
    at com.sun.corba.ee.spi.orbutil.logex.WrapperGenerator$2.invoke(WrapperGenerator.java:511) 
    at com.sun.corba.ee.spi.orbutil.proxy.CompositeInvocationHandlerImpl.invoke(CompositeInvocationHandlerImpl.java:99) 
    at $Proxy117.notSerializable(Unknown Source) 
    at com.sun.corba.ee.impl.orbutil.ORBUtility.throwNotSerializableForCorba(ORBUtility.java:783) 
    at com.sun.corba.ee.impl.encoding.CDROutputStream_1_0.write_abstract_interface(CDROutputStream_1_0.java:697) 
    at com.sun.corba.ee.impl.encoding.CDROutputObject.write_abstract_interface(CDROutputObject.java:545) 
    at com.sun.corba.ee.impl.javax.rmi.CORBA.Util.writeAbstractObject(Util.java:493) 
    ... 

Có ai có ý tưởng gì không?

+0

Nếu bạn tra cứu ejb từ xa thông qua jndi trong mã, bạn có thể sử dụng biến jvm máy chủ cho cổng và máy chủ. Có lẽ nó có thể truy cập các biến jvm trong sun-web.xml. Tôi không biết nếu có thể. – djmj

+0

Tôi muốn giữ mã càng rõ ràng và đơn giản càng tốt. Vì lý do này, tôi không thích sử dụng tra cứu bên trong mã của tôi, nơi @EJB làm cho công việc dễ dàng hơn. – dgisbert

+0

Bạn đã cân nhắc tổ chức hai trường hợp trong một cụm sao? – gcvt

Trả lời

0

@dgisbert

Trong bình luận cuối cùng mà bạn đề cập, đó là một máy chủ là một cộng đồng và khác một là Internal Server của doanh nghiệp của bạn. Cũng gọi lớp Ứng dụng từ một máy chủ công cộng không phải là phương pháp hay nhất. Điều đó có nghĩa là bạn đang trực tiếp cấp quyền truy cập vào lớp kinh doanh quan trọng của mình. Tôi sẽ đề nghị thay vì có một lớp dịch vụ Web trên đầu trang của các cuộc gọi EJB của bạn để mọi cuộc gọi từ trang web công cộng phải đi qua WebServer -> App Server. Bằng cách này, bạn có thể giảm bớt nguy cơ bị tấn công

+0

Cảm ơn câu trả lời, nhưng tôi không thấy lý do tốt hơn nên có lớp Web-Service trung gian thay vì có các cuộc gọi EJB từ xa. Thông qua các cuộc gọi EJB từ xa, tôi đang kiểm soát các phần nào của ứng dụng của tôi được hiển thị từ xa thông qua giao diện từ xa. – dgisbert

+1

@dgisbert - không phải về những dịch vụ mà bạn vạch trần - về việc cấp quyền truy cập cho Lớp doanh nghiệp của bạn cho các Bên bên ngoài một cách trực tiếp. Đề xuất kiến ​​trúc điển hình sẽ có lớp DMZ giữa Hệ thống bên ngoài và bên trong (ftp.software.ibm.com//Google/Bing Search for Securing_Enterprise_Web_Applications_at_the_Source. Nó là một tài liệu dài nhưng phải mất thời gian để đọc nó. Một hacker (Genius guys?) Có thể khai thác lỗ hổng này và tấn công lớp của bạn. Họ tiếp tục đến với các phương pháp tiếp cận mới – user1428716

+0

Cảm ơn một lần nữa cho ý kiến ​​của bạn. Tôi không phải là chuyên gia bảo mật, nhưng tôi lo ngại về vấn đề bảo mật. Tôi đã tải xuống tài liệu bạn đề cập. Nó dài, nhưng tôi sẽ xem xét. Giới thiệu về DMZ, chúng tôi đã có máy chủ 1 trong DMZ. Vì vậy, chúng ta có thể kiểm soát tất cả lưu lượng giữa server1 và server2 thông qua tường lửa của chúng tôi. Tôi gọi nó là public vì chúng tôi cho phép các kết nối web trên server1 (tất nhiên các trang của chúng tôi được bảo vệ bằng mật khẩu) và giữa server1 và server2 chúng tôi chỉ cho phép các cuộc gọi ejb từ xa. Vì vậy, IMHO cũng giống như có một Lớp dịch vụ Web bewteen server1 và server2 có lớp dịch vụ EJB từ xa. – dgisbert

Các vấn đề liên quan