Java SE 6和Java SE 8 JRE在Windows 7上的行为不同(文件权限)

Bar*_*jeu 6 java windows file-permissions windows-7-x64 java-8

我有一个命令行Java应用程序,它在Windows 7 x64平台上读写文件.目前,应用程序与IBM Java SE 6一起运行.结构如下:

APP_ROOT
    some_folder
    jre
        bin
        lib
    myjarfile.jar
    appl_start.bat 
Run Code Online (Sandbox Code Playgroud)

现在,我用解压缩的JRE 8包替换了jre文件夹.并且应用程序开始抱怨它无法在some_folder中"访问"(实际上是它的写操作)文件.如果我在APP_ROOT下手动创建新的some_folder_1并重新配置应用程序以使用它 - 应用程序运行正常.如果我删除新创建的some_folder_1并将some_folder重命名为some_folder_1 - 应用程序抱怨它无法访问它(即使在读取模式下).

如果我用JRE 6文件替换jre文件夹 - 应用程序开始工作正常.

尝试通过属性比较有效权限 - 所有看起来都一样,没有什么可疑的.UAC已打开,我正在工作并在常规用户下更换文件夹.

更新:我在Windows 7中关闭UAC并重新启动后,应用程序开始与JRE 8一起正常工作.但是我需要让它与UAC打开一起工作.将UAC恢复为打开并重新启动时 - 使用JRE 8的应用程序再次失败.此外,注意到似乎JRE 8无法在"C:\ Users\username\AppData\Local\VirtualStore\Program Files(x86)\"中创建正确的文件,它通常在程序尝试在Program Files中编写时创建.

更新2:做了更多的故障排除,并缩小了问题:

  1. 只有在写入"C:\ Program Files\APP_ROOT\some_folder"时,JRE 8的应用程序才会失败
  2. 通过Windows 7设计在这种情况下,文件有望在C:\ User ..\VirtualStore中创建,但是JRE 8无法做到这一点(这是错误的和问题的根源)
  3. JRE 6可以在VirtualStore中创建良好的文件.
  4. 在使用JRE 8重新运行之前,已清理VirtualStore内容
  5. 使用"some_folder_1"和JRE 8组合成功运行是因为JRE 8实际上写在C:\ Program Files/APP_ROOT/some_folder_1内 - 这是违反恕我直言.所以,这是另一个问题 - 为什么JRE 8没有将写入重定向到VirtualStore中的文件系统,而是修改了C:\ Program Files子文件夹.
  6. 如果我将%localusrdir%定义到某个C:\ temp目录,则JRE 8显示同样的问题,因此它不仅仅是VirtualStore文件夹的特定问题,恕我直言.

所以,我得出结论 - 由于某种原因,JRE 8无法将输出写入C:\ Program Files ...重定向到C:\ Users ...\VirtualStore

如何解决这个问题,所以JRE 8开始在JRE 6中开始写入VirtualStore?

更新3:失败的JRE版本:

C:\Program Files (x86)\APP\jre\bin>java.exe -version
java version "1.8.0"
Java(TM) SE Runtime Environment (build pwi3280-20150129_02)
IBM J9 VM (build 2.8, JRE 1.8.0 Windows 7 x86-32 20150116_231420 (JIT enabled, AOT enabled)
J9VM - R28_Java8_GA_20150116_2030_B231420
JIT  - tr.r14.java_20150109_82886.02
GC   - R28_Java8_GA_20150116_2030_B231420
J9CL - 20150116_231420)
JCL - 20150123_01 based on Oracle jdk8u31-b12
Run Code Online (Sandbox Code Playgroud)

Kei*_*ron 2

你不知道。JRE 8 可能告诉 Windows 不要重定向,我想这不是你可以改变的。(顺便说一句,自动重定向到 VirtualStore 是一项 Windows 功能,而不是 Java 功能。)

VirtualStore 适用于旧的和行为不当的程序,而不适用于新的程序。您应该将数据存储在用户/应用程序数据应该存放的位置,在本例中,它将存储在 AppData 中。如果您有现有数据(例如,这是旧程序的升级),那么您应该将数据从该位置迁移到用户可以写入的新位置。

如果您需要多个用户能够写入相同的文件,那么您可能必须修改 ACL/文件权限,以便其他用户可以写入相同的文件 - 这不需要管理员权限。

或者,用户可以取得 APP_ROOT 的所有权/添加写入权限,但这需要管理员权限。

最后,如果您确实想仍然使用 VirtualStore,那么您可以检测 JRE 版本(或进行读/写尝试并捕获异常)并直接使用 VirtualStore 路径,如果是这样,您可能可以正常写入该路径想要的。