퓨즈 ESB (Apache ServiceMix 및 Karaf)에서 OSGI 서비스로 공개하려는 인터페이스가있는 코어 라이브러리가 있습니다. 목표는 다른 번들이이를 사용할 수있게하는 것입니다. 이 서비스는 JPA (OpenJPA)와 Spring을 사용합니다.OSGI 서비스 JPA PersistenceContext가 삽입되지 않았습니다.
public interface PatientService {
public Patient find(Integer id);
}
및 클래스 : 다음은 인터페이스
@Repository
public class PatientServiceJpaImpl implements PatientService {
@PersistenceContext(unitName="psu")
private EntityManager entityManager;
@Override
public Patient find(Integer id) {
return entityManager.find(Patient.class, id);
}
}
다음은 인 META-INF/spring/beans.xml
생략 :
<beans xmlns="http://www.springframework.org/schema/beans" ...>
<context:annotation-config />
<context:component-scan base-package="..." />
<bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="emf" />
</bean>
<bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="persistenceUnitName" value="psu" />
<property name="jpaVendorAdapter" ref="jpaAdapter" />
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.OpenJpaVendorAdapter" />
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.username}" />
<property name="password" value="${database.password}" />
</bean>
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
</beans>
그리고 META-INF/persistence.xml
(약어 사용) :
<persistence xmlns="http://java.sun.com/xml/ns/persistence" ...>
<persistence-unit name="psu" transaction-type="RESOURCE_LOCAL">
<class>...</class>
</persistence>
을
비 OSGi 환경에서는 모든 것이 훌륭하게 작동합니다. 그것은 그래서 OSGi 서비스를 생성, 펠릭스 받는다는 - 번들 - 플러그인을 사용하여, 나는 다음과 같은 OSGI-INF/blueprint/osgi-context.xml
추가 :
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
<bean id="patientService" class="com.test.service.PatientServiceJpaImpl" />
<service id="osgiPatientService" ref="patientService" interface="com.test.service.PatientService" />
</blueprint>
를 번들이 성공적으로 배포되고 서비스가 등록되어 있습니다. 문제는 PatientService
이 다른 번들에서 참조 될 때 엔티티 관리자가 삽입되지 않아서 find(Integer id)
메소드에서 NullPointerException
을 던지는 것입니다. 다음은 소비자의 META-INF/spring/consumer-context.xml
의 조각입니다 :
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:osgi="http://www.springframework.org/schema/osgi"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
http://www.springframework.org/schema/osgi
http://www.springframework.org/schema/osgi/spring-osgi.xsd">
<bean id="patientServiceImpl" class="com.test.ws.PatientWebServiceImpl" >
<property name="patientService">
<osgi:reference interface="com.test.service.PatientService"/>
</property>
</bean>
...
</beans>
그냥 명확하게하기 위해이의
PatientService
소비자 번들에 주입하지만, 엔티티 관리자가 제공 번들에 주입되지 않습니다. 원래 서비스를 시작할 때 또한,이 이유는 다음과 로그 출력에 퍼시스턴스 유닛의 문제로 나타나지 않습니다
125 psu TRACE [SpringOsgiExtenderThread-14] openjpa.Runtime - [email protected] creating container [email protected] for PU psu.
는 무슨 일이 일어나고 있는지 아이디어를 얻을하기를, 나는 개체 메모리 참조를 기록하고 스택 추적은 PatientServiceJpaImpl
클래스의 생성자에 있습니다. 생성자 회 (두 개의 다른 물체를 만드는)라고 하였다
제 1 출력은
org.apache.felix
다소간org.apache.aries.blueprint
끝나는에서 시작 OSGi 컨테이너에서 발생하는 것으로 보인다.두 번째 결과는
org.springframework.osgi
부터 시작하여org.springframework.beans.BeanUtils
으로 끝나는 스프링 프레임 워크에서 비롯된 것 같습니다.
소비자 서비스가 호출되면 참조가 삽입 된 엔티티 관리자가없는 청사진 인스턴스 개체입니다. 또한 로그에서 지속성 단위는 PatientServiceJpaImpl
개체의 청사진 인스턴스 생성 후에 인스턴스화됩니다.
나는이 문제를 꽤 오랫동안 수색 해 봤지만 아이디어가 부족합니다. 아이러니 한 점은 실제로 한 지점에서 효과가 있었다는 것입니다. 그러나 나는 그것이 성공적으로 벗어날 수없는 쥐 둥지 였기 때문에 작동하도록 많은 변화를 만들었습니다.
청사진 관리 객체에 지속성 컨텍스트가 삽입되지 않는 이유는 무엇입니까? 어떤 아이디어라도 감사 할 것입니다. 감사.
응답 해 주셔서 감사합니다. 이 라이브러리는 비 OSGI 환경에서 다른 개발자가 사용합니다. 두 가지 솔루션을 모두 유지할 수있는 방법이 있습니까? 즉, 청사진 환경에서 'PatientServiceJpaImpl'주석을 유지하면 어떤 영향을 미칩니 까? –
그런 경우 청사진을 통해 서비스를 내보내지는 않지만 spring-dm을 사용하여 서비스를 내보내고 있는지 확인하십시오. spring-dm에 스프링 스틱을 사용해야하고 청사진을 통해 서비스를 참조해야하는 경우 둘 모두의 혼합이 작동하지 않습니다. –
원래 스프링 컨텍스트 xml 파일에서 osgi 서비스를 정의하여이를 시도했습니다. 그러나 felix maven-bundle-plugin을 사용하여 번들을 빌드 한 후에 MANIFEST-MF에서 Export-Service 선언을 보지 못했으며 번들을 배포해도 서비스가 등록되지 않았습니다. 나는 봄 DM이 중단 된 것처럼 보이기 때문에 후속 조치를하지 않기로 결정했다. karaf에서 spring-dm을 사용할 수 있습니까? (Fuse ESB 배포판을 사용하고 있습니까?) 그렇다면 길 아래로하는 것이 합리적입니까? 감사. –