问题
I'm working on an application that requires the use of both JPA/Hibernate and RMI. Since RMI requires the use of a Security Policy to make sure that access to the network is correctly assigned I also now have to worry about the folder permissions.
I've been looking online (and here at SO) for a couple of days now trying to find a solution to this problem. Basically the problem is that for JPA/Hibernate to work I have to place the persistence.xml
file in the META-INF
directory, and the META-INF
directory must be under the src
directory of my project (which doesn't make sense to me either but it works). So that the project layout is basically:
org.project.root
|
|>src
| |
| |>org.project.package
| |
| |>META-INF
| |
| |>persistence.xml
|
|>config
|
|>database
|
|>logs
My security policy file I've been trying to grant read access to the folder ${user.dir}${/}src${/}META-INF${/}-
, however, when I try to run the application I get the error No Persistence provider for EntityManager named DERBY_ACPSTORE_CREATE
. My persistence.xml file however does contain this, and it works when comment out all the RMI stuff and stop reading the security policy. So my question is how can I get my security policy file to allow me to read the persistence.xml file?
UPDATE 1
Using the suggested path information from @Vineet Reynolds I'm able to see the file's path using:
File f = new File("META-INF/persistence.xml");
System.out.println(f.getAbsolutePath());
However, I'm still getting this error when I'm trying to create the database.
javax.persistence.PersistenceException: No Persistence provider for EntityManager named DERBY_ACPSTORE_CREATE
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:55)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:33)
at org.myproject.data.DBInit.dbInit(DBInit.java:29)
at org.myproject.ACPStoreMainService.main(ACPStoreMainService.java:91)
My persistence.xml as I said worked fine before I started using the security policy so I know that the persistence-unit "DERBY_ACPSTORE_CREATE" is present and correct.
Update 2
Although I'm not sure what good this is since it worked when I don't use the Security Policy here's my persistence.xml contents:
<?xml version="1.0" encoding="UTF-8"?>
<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_1_0.xsd" version="1.0">
<persistence-unit name="DERBY_ACPSTORE_CREATE">
<provider>org.hibernate.ejb.HibernatePersistence</provider
<class>org.myproject.data.MessageHistory</class>
<properties>
<property name="hibernate.connection.driver_class"
value="org.apache.derby.jdbc.EmbeddedDriver" />
<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyDialect" />
<property name="hibernate.connection.url" value="jdbc:derby:database/acpstore;create=true" />
<property name="hibernate.show_sql" value="true" />
<property name="hibernate.format_sql" value="true" />
<property name="use_sql_comments" value="true" />
<property name="hibernate.hbm2ddl.auto" value="create" />
<property name="hibernate.connection.username" value="user" />
<property name="hibernate.connection.password" value="password" />
</properties>
</persistence-unit>
</persistence>
UPDATE 3
As I mentioned in the comment to the answer from Vineet Reynolds below I've tested the persistence.xml without the security and it is now working. Then when I reinstate the security policy then I get the errors again. As such below is the contents of my security policy and how I create the security in my application:
grant {
permission java.lang.RuntimePermission "shutdownHooks";
permission java.lang.RuntimePermission "readFileDescriptor";
permission java.lang.RuntimePermission "writeFileDescriptor";
permission java.util.PropertyPermission "user.dir", "read";
permission java.net.SocketPermission "172.10.10.21:1024-65535", "connect, accept, resolve";
permission java.net.SocketPermission "172.10.10.21:1-1023", "connect,resolve";
permission java.io.FilePermission "${user.dir}${/}META-INF${/}-", "read";
permission java.io.FilePermission "${user.dir}${/}config${/}-", "read, write, delete";
permission java.io.FilePermission "${user.dir}${/}database${/}-", "read, write, delete";
};
And this is what happens in my application to set the security manager
if(System.getSecurityManager() == null)
{
System.setSecurityManager(new RMISecurityManager());
}
UPDATE 4
I've found a message that I didn't notice before coming from log4j. The message is
[main] INFO org.hibernate.ejb.Ejb3Configuration - Could not find any META-INF/persistence.xml file in the classpath
which seems odd to me. So I listed the directories in the classpath and I found org.project.root\bin
but not org.project.root
. I know now that the META-INF in the runtime is located as org.project.root\META-INF
, and that the classpath should point to the org.project.root
so that JPA and hibernate can access find the persistence.xml. So would could it be that I need to somehow change the classpath to match this?
回答1:
The original question does not indicate if the src
directory is present in the runtime environment or not. I would assume that it is not present in the runtime environment, for reasons stated below.
The src
directory is an artifact that is usually required during development to represent the source directory. At runtime, this directory is usually not present in the directory structure (of a JAR file).
You might be better off specifying the permission as one to grant read access to:
${user.dir}${/}META-INF${/}-
Edit:
Based on the fact that no SecurityExceptions are thrown, and that a PersistenceExcpetion is thrown, it appears that the contents of the persistence.xml might be invalid. The following questions at StackOverflow could be referenced, but the resolution need not be exactly the same as depicted in the answers.
- javax.persistence.PersistenceException: No Persistence provider for EntityManager named customerManager
- No Persistence provider for EntityManager named …
回答2:
I'll give Vineet a up vote for helping me with knowing where the META-INF folder ends up, however, I finally figured out what my permissions problem is.
The java.io.FilePermission
is hierarchical, meaning you have to give "read" access to higher folders before you can give it to lower directories.
Basically in my security policy file I should have done permission java.io.FilePermission "${user.dir}${/}-", "read";
first before I entered permission java.io.FilePermission "${user.dir}${/}META-INF${/}-", "read";
来源:https://stackoverflow.com/questions/6148730/what-are-the-correct-security-policy-value-settings-to-allow-both-rmi-and-jpa-hi