2013-06-05 1 views
0

RMI를 사용하여 몇 대의 원격 서버로 작업량을 보내는 프로토 타입을 완성하려고합니다. 작업이 완료되면 원격 서버는 결과를 다시 데이터베이스에 기록합니다. 필자는 JPA와 Hibernate를 공급자로 사용한다. 그러나 원격 서버에 그렇게하도록 요청하는 데 어려움을 겪고 있습니다. 여기 RMI를 통해 원격 서버에 JPA EntityManagerFactory를 시작하십시오.

이 부분의 코드는 다음
public class UpdateDB implements ServerRun<Boolean>, Serializable { 

private static final long serialVersionUID = 2683781993159094346L; 

@Override 
public Boolean execute() { 
    EntityManagerFactory entityManagerFactory = Persistence.createEntityManagerFactory("abc"); 
    EntityManager entityManager = entityManagerFactory.createEntityManager(); 
    entityManager.getTransaction().begin(); 
    entityManager.persist(new User("First user!", new Date())); 
    entityManager.persist(new User("Second user", new Date())); 
    entityManager.getTransaction().commit(); 
    entityManager.close(); 

    entityManager.close(); 
    entityManagerFactory.close(); 
    return true; 
    } 
} 

위와 같은 레벨의 코드 리소스/META-INF에서의 persistence.xml이다 RMI를 통해 원격 서버로 전송 될 예정이다 :

나는 그것이 작동하는 서버에 JPA를 실행하면

<persistence xmlns="http://java.sun.com/xml/ns/persistence" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd" 
version="2.0"> 

<persistence-unit name="abc" transaction-type="RESOURCE_LOCAL"> 
    <provider>org.hibernate.ejb.HibernatePersistence</provider> 
    <class>data.persist.User</class> 

    <properties> 
     <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" /> 
     <property name="javax.persistence.jdbc.url" value="jdbc:mysql://192.168.205.103:3306/event_grp" /> 
     <property name="javax.persistence.jdbc.user" value="username" /> 
     <property name="javax.persistence.jdbc.password" value="password" /> 

     <property name="hibernate.show_sql" value="true" /> 
     <property name="hibernate.hbm2ddl.auto" value="create" /> 
    </properties> 

</persistence-unit> 

, 아무것도 다른 RMI 기능의 측면에서 작동합니다. 그러나의 EntityManagerFactory이 시작되지 않습니다, 여기에 오류는 다음과 같습니다

Exception in thread "main" javax.persistence.PersistenceException: No Persistence provider for EntityManager named abc 
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:69) 
    at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:47) 
    at data.persist.UpdateDB.execute(UpdateDB.java:58) 
    at data.persist.UpdateDB.execute(UpdateDB.java:1) 
    at engine.ComputeEngine.executeTask(ComputeEngine.java:39) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
    at java.lang.reflect.Method.invoke(Method.java:597) 
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:303) 
    at sun.rmi.transport.Transport$1.run(Transport.java:159) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at sun.rmi.transport.Transport.serviceCall(Transport.java:155) 
    at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:535) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:790) 
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:649) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
    at java.lang.Thread.run(Thread.java:662) 
    at sun.rmi.transport.StreamRemoteCall.exceptionReceivedFromServer(Unknown Source) 
    at sun.rmi.transport.StreamRemoteCall.executeCall(Unknown Source) 
    at sun.rmi.server.UnicastRef.invoke(Unknown Source) 
    at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(Unknown Source) 
    at java.rmi.server.RemoteObjectInvocationHandler.invoke(Unknown Source) 
    at com.sun.proxy.$Proxy12.executeTask(Unknown Source) 
    at client.JobSubmitter.main(JobSubmitter.java:94) 

그래서는 RMI를 찾거나 META-INF에있는 persistence.xml을로드하지 못할 것으로 보인다. 그리고 log4j도 비슷한 경험을했지만 log4j.properties 파일 대신 코드의 모든 것을 정의함으로써 해결했습니다. 코드가 원격 서버로 전송하기위한 패키지의 모습이 내가 persistence.xml을 배치 유일한 장소입니다 : user1888440의 질문 당

-src/main/java/data/persist/UpdataDB.java 
| 
src/main/resources/META-INF/persistence.xml 

를, 내가 보안을 넣어 편집

여기서 허가 구성. 그리고 클라이언트와 원격 서버 모두 다음과 같은 권한을 사용

grant { 
permission java.security.AllPermission; 
}; 
내가 다시 데이터베이스에 쓸 수 있도록 원격 서버의 EntityManagerFactory를 초기화 할 수있는 방법

? 간단한 코드를 제공 할 수 있다면 많은 것을 받아 들일 것입니다.

+0

이것이 어떻게 RMI와 관련이 있는지 알 수 없습니다. 그것은 당신의 지속성 구성에 관한 것입니다. – EJP

+0

로컬 컴퓨터에서 지속성을 유지하는 것이 좋습니다. RMI를 통해 원격 서버로 보낼 때 작동하지 않습니다. 그리고 이것이 의미가있는 경우 RMI 태그를 다시 추가하십시오. –

답변

0

원격 서버는 클라이언트와 동일한 리소스에 액세스해야합니다. 누가 데이터베이스에 실제로 손을 대고 싶습니까? 누군가? 그렇다면 각 참가자는 데이터베이스에 대한 연결을 만들 수 있도록 persistence.xml의 복사본이 필요합니다.

+0

답장을 보내 주셔서 감사합니다. 'UpdateDB'클래스가있는 패키지 된 jar 파일에 persistence.xml의 복사본이 있습니다. 문제는 작업 제출자가 원격 서버에 'UpdateDB'를 보낼 때 원격 서버가 'UpdateDB'의 클래스 경로에 있어도 classloader에서 persistence.xml을 가져올 수 없다는 것입니다. 이것은, RMI 리모트 클래스 로더의 동작에 원인이있을 가능성이 높습니다. –

+0

구성에 대해 더 많이 알지 못해도별로 도움이되지 않습니다. 그러나 persistence.xml에 대한 사용 권한을 확인하고자 할 수 있습니다. RMI에서는 종종 설정에 따라 특정 권한 부여 권한을 부여해야합니다. grant codebase와 같이 "file : /whatever/persistence.xml"{ permission java.security.AllPermission; }; –

+0

패키징 및 persistence.xml이있는 위치는 편집 된 구성을 참조하십시오. 권한은 클라이언트와 원격 서버 모두에 {permission java.security.AllPermission;}을 부여하도록 설정됩니다. –