允许 RMI 和 JPA/Hibernate 同时工作的正确安全策略值设置是多少
我正在开发一个需要使用 JPA/Hibernate 和 RMI 的应用程序。由于 RMI 需要使用安全策略来确保正确分配对网络的访问权限,因此我现在还必须担心文件夹权限。
我已经在网上(以及这里)寻找了几天,试图找到这个问题的解决方案。基本上问题是,为了让 JPA/Hibernate 工作,我必须将 persistence.xml 文件放在 META-INF 目录中,并将 META-INF< /code> 目录必须位于我的项目的 src 目录下(这对我来说也没有意义,但它有效)。因此,项目布局基本上是:
org.project.root
|
|>src
| |
| |>org.project.package
| |
| |>META-INF
| |
| |>persistence.xml
|
|>config
|
|>database
|
|>logs
我的安全策略文件我一直在尝试授予对文件夹 ${user.dir}${/}src${/}META-INF${/} 的读取权限-
,但是,当我尝试运行该应用程序时,我收到错误No Persistence provider for EntityManager named DERBY_ACPSTORE_CREATE
。然而,我的 persistence.xml 文件确实包含此内容,并且当注释掉所有 RMI 内容并停止读取安全策略时它会起作用。所以我的问题是如何获取安全策略文件以允许我读取 persistence.xml 文件?
更新 1
使用 @Vineet Reynolds 的建议路径信息,我可以使用以下命令查看文件的路径:
File f = new File("META-INF/persistence.xml");
System.out.println(f.getAbsolutePath());
但是,当我尝试创建数据库时,我仍然收到此错误。
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)
正如我所说,在开始使用安全策略之前,我的 persistence.xml 工作正常,因此我知道持久性单元“DERBY_ACPSTORE_CREATE”存在且正确。
更新 2
虽然我不确定这有什么好处,因为它在我不使用安全策略时有效,这是我的 persistence.xml 内容:
<?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>
更新 3
正如我提到的在下面对 Vineet Reynolds 的答案的评论中,我已经在没有安全性的情况下测试了 persistence.xml,它现在正在工作。然后,当我恢复安全策略时,我再次收到错误。因此,下面是我的安全策略的内容以及如何在我的应用程序中创建安全性:
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";
};
这就是我的应用程序中设置安全管理器时发生的情况
if(System.getSecurityManager() == null)
{
System.setSecurityManager(new RMISecurityManager());
}
更新 4
我发现了一条消息,我来自log4j之前没有注意到。这个消息
[main] INFO org.hibernate.ejb.Ejb3Configuration - Could not find any META-INF/persistence.xml file in the classpath
对我来说似乎很奇怪。因此,我列出了类路径中的目录,并找到了 org.project.root\bin,但没有找到 org.project.root。我现在知道运行时中的 META-INF 位于 org.project.root\META-INF ,并且类路径应指向 org.project.root > 这样JPA和hibernate就可以访问找到persistence.xml。那么我是否需要以某种方式更改类路径以匹配它?
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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
原始问题并未表明 src 目录是否存在于运行时环境中。我认为它不存在于运行时环境中,原因如下。
src
目录是开发过程中通常需要的一个工件,用于表示源目录。在运行时,该目录通常不存在于(JAR 文件的)目录结构中。您最好将权限指定为授予读取访问权限:
编辑:
基于没有抛出 SecurityExceptions 且抛出 PersistenceExcpetion 的事实,看来持久化的内容.xml 可能无效。可以参考 StackOverflow 上的以下问题,但解决方案不必与答案中描述的完全相同。
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:
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.
我会给 Vineet 投票,因为他帮助我了解 META-INF 文件夹的最终位置,但是,我终于弄清楚了我的权限问题是什么。
java.io.FilePermission 是分层的,这意味着您必须先授予对较高文件夹的“读取”访问权限,然后才能将其授予较低目录。
基本上在我的安全策略文件中,我应该在输入
permission java 之前先完成
permission java.io.FilePermission "${user.dir}${/}-", "read";
.io.FilePermission "${user.dir}${/}META-INF${/}-", "读取";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 enteredpermission java.io.FilePermission "${user.dir}${/}META-INF${/}-", "read";