I am trying to finish a prototype that using RMI to send workload to a few remote servers. After the work is done, the remote servers are supposed to write the result back to the database. I use JPA with Hibernate as the provider. But I am having a difficult time to ask the remote server to do so.
Here is code for the part is going to be sent to the remote server through 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;
}
}
Here is the persistence.xml in the resources/META-INF at the same level of the code above:
<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>
If I run the JPA on the server it works, and anything else works in terms of RMI functions. But the EntityManagerFactory will not start, here is the error:
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)
So, it seems that the RMI cant find or load the persistence.xml in the META-INF. And I had similar experience with log4j as well, but I got around by defining everything in the code instead of using the log4j.properties file.
Edit: The package for the code to be sent to the remote server looks like and this is the only place that I placed the persistence.xml:
-src/main/java/data/persist/UpdataDB.java
|
src/main/resources/META-INF/persistence.xml
Per user1888440's question, I put the security permission configuration here. And both client and remote servers use the following permissions:
grant {
permission java.security.AllPermission;
};
How can I make the remote server to initialize the EntityManagerFactory so it can write back to the database? I would appreciate a lot if you can provide some simple code as well.