2013-06-05 31 views
0

我正试图完成一个使用RMI将工作负载发送到少数远程服务器的原型。工作完成后,远程服务器应该将结果写回数据库。我使用Hibernate作为提供者的JPA。但是我现在很难问远程服务器这样做。通过RMI启动远程服务器中的JPA EntityManagerFactory

这里是该部分代码是要通过RMI被发送到远程服务器

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中:

<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> 

如果我它工作在服务器上运行的JPA,和别的作品中的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中唯一的地方:

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

每user1888440的问题,我把安全权限配置在这里。与客户端和远程服务器使用以下权限:

grant { 
permission java.security.AllPermission; 
}; 

我怎样才能让远程服务器初始化的EntityManagerFactory,因此可以写回数据库?如果您可以提供一些简单的代码,我将非常感激。

+0

我看不出这与RMI有什么关系。它关于您的持久性配置。 – EJP

+0

它可以在本地机器上持久工作。它通过RMI发送到远程服务器时不起作用。如果这对您有意义,请添加RMI标签。 –

回答

0

远程服务器将需要与客户端相同的资源访问权限。你想实际接触数据库的人是谁?任何人?如果是这样,那么每个参与者都需要一个persistence.xml的副本,以便他们可以创建与数据库的连接。

+0

感谢您的回复。在包装的jar中有'UpdateDB'类的persistence.xml的副本。问题是,当作业提交者将'UpdateDB'发送到远程服务器时,远程服务器将无法从类加载器获取persistence.xml,即使它在'UpdateDB'的类路径中。这很可能是由R​​MI远程类加载器的行为引起的,我并不完全理解这一点。 –

+0

不知道更多关于你的配置我不能帮助太多。但是你可能想要检查persistence.xml的权限。通常在RMI中,您必须根据设置给予特定的授予权限。像授予代码库“文件:/whatever/persistence.xml”权限java.security.AllPermission; }; –

+0

请参阅已编辑的打包配置以及persistence.xml的放置位置。该权限设置为为客户端和远程服务器授予{permission java.security.AllPermission;}权限。 –