2012-05-31 4 views
0

MySQL 5.5, Glassfish 3.1.2 및 독립 실행 형 Swing 클라이언트 (JRE 6_u32)를 사용하여 3 계층 응용 프로그램을 만들었습니다. Glassfish 서버에서 실행중인 GUI 업데이트 서비스를 계획하므로 다른 사용자가 @Entity 주석 객체를 작성, 수정 또는 제거 할 때 현재 응용 프로그램 서버에 연결된 모든 사용자에게 알립니다.Java-EE6 : JMS 토픽 제공자로 사용할 세션 Bean의 유형은 무엇입니까?

그 목적을 위해 엔티티 리스너가 콜백 메소드 (@PostPersist, @PostUpdate, @PostRemove)를 호출하는 즉시 JMS 토픽 프로듀서 역할을하는 세션 빈을 계획합니다. 독립 실행 형 Swing 클라이언트는 이에 따라 JMS 메시지 사용자로 작동합니다.

내 응용 프로그램은 3 개의 프로젝트로 구성됩니다. 먼저 EJB 프로젝트 마녀가 서버 컨테이너 내에서 실행되고 @Entity 주석이있는 클래스와 원격 Facade 인터페이스를 보유한 클래스 라이브러리 프로젝트 인 Facade 세션 Bean을 보유합니다.이 EJB 프로젝트는 EJB 프로젝트와 독립 실행 형 Swing 클라이언트가 inter 통신 목적) 그리고 마지막으로 GUI를 관리하는 독립 실행 형 스윙 클라이언트. @Singleton 클래스는 classlib 프로젝트의 일부이므로 종속성 주입을 사용할 수 없습니다. 또한 이것이 정확히 문제라고 생각합니다. @Singleton 클래스는 자체 jar-lib에 압축되어 있으며 EJB 프로젝트에서 참조하므로 (JNDI 조회를 사용해야 함) 컨테이너 관리되지 않습니다.

응용 프로그램 서버에서 주제 메시지 생성자를 구현하는 데 어떤 종류의 세션 Bean을 권장 하시겠습니까? Singleton, Stateful, Stateless, Message-Driven?

여기 내 싱글 톤 세션 빈이 있습니다. 문제는 @PostConstruct 주석이 달린 initConnection 메서드가 어떻게 든 호출되지 않는다는 것입니다. publishCreated()가 호출 될 때 'session'및 'publisher'필드는 null입니다 ...

이 아이디어를 해결하는 방법은 무엇입니까? 미리 많은 감사드립니다!

@Singleton 
public class UpdateService { 

    private Destination topic; 
    private ConnectionFactory factory; 
    private Connection connection; 
    private Session session; 
    private MessageProducer producer; 

    public UpdateService() { } 

    @PostConstruct void initConnection() { 
     try { 
      InitialContext ctx = ServerContext.getInitialContext(); 
      factory = (TopicConnectionFactory)ctx.lookup("jms/TopicFactory"); 
      topic = (Topic)ctx.lookup("jms/TopicUpdate"); 
      connection = factory.createConnection(); 
      session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE); 
      producer = session.createProducer(topic); 
     } catch (NamingException ex) { 
      Logger.getLogger(UpdateService.class.getName()).log(Level.SEVERE, ex.getMessage(), ex); 
     } catch (JMSException ex) { 
      Logger.getLogger(UpdateService.class.getName()).log(Level.SEVERE, ex.getMessage(), ex); 
     } 
    } 

    @PreDestroy void closeConnection() { 
     try { 
      session.close(); 
      connection.close(); 
     } catch (JMSException ex) { 
      Logger.getLogger(UpdateService.class.getName()).log(Level.SEVERE, ex.getMessage(), ex); 
     } 
    } 

    @PostPersist void publishCreated(IUpdateableEntity entity) throws JMSException { 
     if(session!=null && producer!=null) { 
      ObjectMessage message = session.createObjectMessage(new UpdateMessage(entity, UpdateType.CREATED)); 
      producer.send(message); 
     } 
    } 

    @PostUpdate void publishUpdated(IUpdateableEntity entity) throws JMSException { 
     if(session!=null && producer!=null) { 
      ObjectMessage message = session.createObjectMessage(new UpdateMessage(entity, UpdateType.MODIFIED)); 
      producer.send(message); 
     } 
    } 

    @PostRemove void publishRemoved(IUpdateableEntity entity) throws JMSException { 
     if(session!=null && producer!=null) { 
      ObjectMessage message = session.createObjectMessage(new UpdateMessage(entity, UpdateType.REMOVED)); 
      producer.send(message); 
     } 
    } 

} 
+0

싱글 톤 빈에'@ Startup' 주석을 추가하려고 했습니까? –

+0

안녕하세요. 귀하의 제안에 감사드립니다. @Startup으로 이미 시도했지만, 주제에 대한 연결을 설정할 수 없다는 예외가 발생합니다. JMS 시스템이 시작되기 전에 컨테이너가 싱글 톤을 인스턴스화하려고 시도했기 때문에 아마 ... 다른 어떤 아이디어로 문제를 해결할 수 있을까요? – salocinx

답변

1

Bean을 초기화하는 동안 종속성을 주입하는 서버의 책임. 주석을 사용하여 이러한 JMS 자원을 주입 할 수 있습니다.

@Startup 
@Singleton 
public class UpdateService { 

    @Resource(mappedName = "jms/TopicFactory") 
    private ConnectionFactory connectionFactory; 

    @Resource(mappedName = "jms/TopicUpdate") 
    private Topic replyToTestQueue; 

    @PostConstruct 
    void initConnection() { 

      //-- Messaging Configuration 
    } 
} 

관리 콘솔을 통해 이러한 리소스가 올바르게 구성되었는지 확인하십시오. 나는 글래스 피쉬에 익숙하지 않지만, &은 잘 동작했다.

기본적으로 모든 싱글 톤 메소드는 트랜잭션 & 스레드 안전성을 가지므로 명시 적으로 잠금으로써 동시성을 관리 할 수 ​​있습니다. 그렇지 않으면 상태에 맞지 않는 bean을 사용할 수 있습니다.

+0

감사합니다. 나는 중요한 사실을 언급하는 것을 잊었다. 내 신청서는 3 개의 프로젝트로 구성됩니다. 먼저 EJB 프로젝트 마녀는 서버 클래스, 엔티티 클래스와 원격 Facade 인터페이스 (이것은 상호 통신을 위해 EJB와 클라이언트에 의해 공유 됨) 및 독립 실행 형 스윙 클라이언트를 포함하는 클래스 라이브러리 내에서 실행됩니다. @ Singleton 클래스는 classlib 프로젝트의 일부이므로 종속성 주입을 사용할 수 없습니다. 게다가 이것이 정확히 문제라고 생각합니다. @Singleton 클래스는 컨테이너 관리가 아닙니다. 자동화 된 초기화를 수행 할 또 다른 가능성이 있습니까? – salocinx

+0

@salocinx EJB 프로젝트의 일부가 아니며 응용 프로그램 서버와 함께 실행되지 않기 때문에 이러한 주석이 작동하지 않습니다. 나는 classlib가 여기 자바 프로젝트라는 것을 가정한다. EJB 프로젝트와 클래스 라이브러리로 싱글 톤을 GUI와 EJB 프로젝트 사이의 조정자로 옮길 수는 없습니까?또한 엔터티 수신기 EJB 프로젝트의 일부로, 그래서 거기에서 메시지를 생산할 수 있다고 생각, 싱글 톤은 동일한 응용 프로그램에있을 것입니다. –

+0

@ Nayan. 불행히도 엔티티 리스너는 classlib 프로젝트의 일부이기도합니다. @ Entity 주석 클래스는 EJB 프로젝트와 독립 실행 형 스윙 클라이언트 간의 상호 통신 목적을 위해 classlib 프로젝트에 머물러 있기 때문입니다. 엔터티 리스너와 @ Entity 클래스를 classlib에 남겨둔 채 @ Singleton 메시지 생성자를 EJB로 이동 한 다음 엔터티 수신기가 이벤트를 트리거 할 때 싱글 톤에서 비즈니스 메서드를 호출합니까? 또는이 경우 중재자를 어떻게 설계 하시겠습니까? – salocinx

관련 문제