开发者问题收集

如何使用 Java 管理 Windows VM 上其他用户的文件权限

2020-09-09
482

我正在编写 Jmeter 脚本,但在控制 JSR223 采样器中的某些文件处理时遇到了麻烦。问题是我需要创建一个本地文件,但如果该文件名已经存在,我想在重新创建之前将其删除。我的代码在我的笔记本电脑(Windows 10)上运行良好,但我现在正在将我的 Jmeter 脚本移植到测试环境中的虚拟机中,这似乎是问题的一部分。VM 运行的是 Windows Server 2019,但这只是理论上的。我使用标准的内部公司凭据将 RDC 连接到该计算机。

我的问题是:我如何强制删除文件,或单独修改其系统访问权限以便删除操作可以继续。

我是一名 Java 新手程序员,但除此之外,我还是一名经验丰富的集成商,在许多编码语言方面拥有丰富的经验,可追溯到 30 多年前。

Java 版本:

  • 我的本地计算机:v8 Update 261
  • 虚拟机:v8 Update 261

Jmeter 版本:

  • 我的本地计算机:Jmeter 5.2.1
  • 虚拟机:Jmeter 5.3

根本原因似乎是在 VM 上,当我的 Jmeter 任务创建文件,然后在 Windows 资源管理器中检查它时:我的帐户具有完全权限,而本地主机上的“用户”帐户仅具有读取权限(参见所附屏幕截图)。当我的代码需要删除文件时,Jmeter 脚本似乎只能访问只读版本,因此无法删除或覆盖它。
不同用户的文件属性

请注意,如果我在 Windows 中手动编辑访问属性,以便本地用户具有完全访问权限,则我的代码运行不会出现任何问题,并且文件将被删除。

到达删除方法时,我的控制台日志会报告以下消息:

JSR223Sampler: Problem in JSR223 script Build plink Script File (BSS MNP File ), message: javax.script.ScriptException: java.io.FileNotFoundException: D:\SLAB Automation\Jmeter Scripts\scripts\check_bss_mnp_BRP_files.plink (Access is denied)

这是我的代码,它是 Groovy 脚本引擎内的 Java。

//  if the file exists. If it does, delete it and recreate it.
f= new File(fPath);
if (f.exists()) { 
    log.info("File " + fName + " exists.. deleting it.");
    System.gc();            // Run Garbage collection (Found a solution that suggests to do this, but it makes no difference)
    f.setWritable(true);    // Try modifying the permissions; also fails.
    f.delete();             // *** Here is my problem ***
} 

// Open File 
f = new FileOutputStream(fPath, false);     // Second param: true to append; false to overwrite (what we want)
p = new PrintStream(f); 
// Write data to file 
p.println( "*** my content ***");
// Close File(s)
p.close();
f.close();
log.info("-- Created file: " + fPath);

对于任何需要堆栈跟踪的人,为了完整起见,这里是它:

2020-09-09 18:32:21,317 ERROR o.a.j.p.j.s.JSR223Sampler: Problem in JSR223 script Build plink Script File (BSS MNP File ), message: javax.script.ScriptException: java.io.FileNotFoundException: D:\SLAB Automation\Jmeter Scripts\scripts\check_bss_mnp_BRP_files.plink (Access is denied)
javax.script.ScriptException: java.io.FileNotFoundException: D:\SLAB Automation\Jmeter Scripts\scripts\check_bss_mnp_BRP_files.plink (Access is denied)
    at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:320) ~[groovy-jsr223-3.0.3.jar:3.0.3]
    at org.codehaus.groovy.jsr223.GroovyCompiledScript.eval(GroovyCompiledScript.java:71) ~[groovy-jsr223-3.0.3.jar:3.0.3]
    at javax.script.CompiledScript.eval(Unknown Source) ~[?:1.8.0_261]
    at org.apache.jmeter.util.JSR223TestElement.processFileOrScript(JSR223TestElement.java:222) ~[ApacheJMeter_core.jar:5.3]
    at org.apache.jmeter.protocol.java.sampler.JSR223Sampler.sample(JSR223Sampler.java:72) [ApacheJMeter_java.jar:5.3]
    at org.apache.jmeter.threads.JMeterThread.doSampling(JMeterThread.java:630) [ApacheJMeter_core.jar:5.3]
    at org.apache.jmeter.threads.JMeterThread.executeSamplePackage(JMeterThread.java:558) [ApacheJMeter_core.jar:5.3]
    at org.apache.jmeter.threads.JMeterThread.processSampler(JMeterThread.java:489) [ApacheJMeter_core.jar:5.3]
    at org.apache.jmeter.threads.JMeterThread.run(JMeterThread.java:256) [ApacheJMeter_core.jar:5.3]
    at java.lang.Thread.run(Unknown Source) [?:1.8.0_261]
Caused by: java.io.FileNotFoundException: D:\SLAB Automation\Jmeter Scripts\scripts\check_bss_mnp_BRP_files.plink (Access is denied)
    at java.io.FileOutputStream.open0(Native Method) ~[?:1.8.0_261]
    at java.io.FileOutputStream.open(Unknown Source) ~[?:1.8.0_261]
    at java.io.FileOutputStream.<init>(Unknown Source) ~[?:1.8.0_261]
    at java.io.FileOutputStream.<init>(Unknown Source) ~[?:1.8.0_261]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:1.8.0_261]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) ~[?:1.8.0_261]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) ~[?:1.8.0_261]
    at java.lang.reflect.Constructor.newInstance(Unknown Source) ~[?:1.8.0_261]
    at org.codehaus.groovy.reflection.CachedConstructor.invoke(CachedConstructor.java:72) ~[groovy-3.0.3.jar:3.0.3]
    at org.codehaus.groovy.runtime.callsite.ConstructorSite$ConstructorSiteNoUnwrapNoCoerce.callConstructor(ConstructorSite.java:105) ~[groovy-3.0.3.jar:3.0.3]
    at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCallConstructor(CallSiteArray.java:59) ~[groovy-3.0.3.jar:3.0.3]
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:263) ~[groovy-3.0.3.jar:3.0.3]
    at org.codehaus.groovy.runtime.callsite.AbstractCallSite.callConstructor(AbstractCallSite.java:286) ~[groovy-3.0.3.jar:3.0.3]
    at Script115.run(Script115.groovy:40) ~[?:?]
    at org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.eval(GroovyScriptEngineImpl.java:317) ~[groovy-jsr223-3.0.3.jar:3.0.3]
    ... 9 more
2个回答

您能否执行以下操作并检查它是否有效?

  1. 确保目录/文件夹 D:\SLAB Automation\Jmeter Scripts\scripts\ 在执行 JMeter 脚本的机器中存在。

It is a good practice to avoid using spaces in directory/folder names. You may remove the spaces in the directories and update the test plan accordingly.

  1. 请确保登录用户有权读取/写入系统文件。根据您的输入,似乎您在这里没有任何问题

  2. 您可以尝试使用 Java IDE(如 IntelliJ idea)运行 groovy 脚本,并确认您的脚本也在您的 VM 上运行。

我希望这对您有用。

Janesh Kodikara
2020-09-10

我决定绕过我的问题,而不是按照我最初考虑的方式解决它。我曾想知道是否有任何 Java 方法可以触及 Windows 操作系统级别,以提升文件权限或覆盖它们。我知道 Java 是一种虚拟机,鼓励可移植代码,因此这种解决方案违背了精神。此外,这远远超出了我的 Java 知识范围。

无论如何,我意识到我需要创建的文件也需要特定于正在进行的测试运行。随着我的 Jmeter 脚本变得越来越复杂,甚至可能有多个线程组并行运行,我不希望两个 TG 尝试将相同的文件名用于不同的目的而出现竞争条件。

解决方案:每个上下文和测试运行都有唯一的文件名。我将它们存储在特定于 TempFiles 的文件夹中,甚至在其中动态创建每月子文件夹以帮助在主机上进行文件管理。它正在发挥作用,这是最重要的。

Nigel Domaingue
2020-09-15