gpt4 book ai didi

java - FEST:启动/停止使用 System.exit() 而不影响 VM 的外部 SWING 程序

转载 作者:搜寻专家 更新时间:2023-11-01 03:38:38 24 4
gpt4 key购买 nike

在我的 Cucumber-jvm 场景中,我需要在每个场景之前运行一个外部 jar 程序,在步骤中使用 FEST 库与之交互,最后关闭程序以清理下一个场景的历史。我需要的特定外部程序使用 System.exit() 在关闭时退出。反过来,我不能在我的测试中退出程序,因为那样会终止整个虚拟机。相反,我使用 FEST 中内置的自定义 SecurityManager 来覆盖 System.exit() 调用。但是,我无法让它正常工作。

下面示例 1 中的代码尝试在 Cucumber @Before Hook 中启动外部程序,并在 @After 中关闭它钩。当我运行 mvn verify 时,它仅适用于一种情况。然而,对于两个或多个场景,maven 只是卡在线上:

-------------------------------------------------------
T E S T S
-------------------------------------------------------
Running test.acceptance.CucumberRunner

之后什么也没有发生。我可以看到外部程序启动并关闭了一次,但第二次启动时却没有关闭。当我手动关闭它时,maven 输出以下内容:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-failsafe-
plugin:2.16:integration-test (default) on project acceptance-tests: Execution default of
goal org.apache.maven.plugins:maven-failsafe-plugin:2.16:integration-test failed: The
forked VM terminated without saying properly goodbye. VM crash or System.exit called ?

有人知道这里发生了什么吗?看起来问题是外部程序根本没有终止 - 可能是我正在使用的 NoExitSecurityManagerInstaller 的错误。但是,我不知道如何防止调用 System.exit 终止整个虚拟机。不知何故,我只想退出我启动的程序而不影响运行它的 VM。这不可能吗?

更新 - 找到解决方案!

玩了几个小时的代码,无意间发现WindowFinder使用的Robot类有一个cleanUp方法那:“清理这个机器人使用的任何已用资源(键盘、鼠标、打开的窗口和{@link ScreenLock})。”。我尝试使用它代替 frame.close(),结果证明它有效!它甚至不需要自定义 SecurityManager

问题似乎是 BasicRobot.robotWithCurrentAwtHierarchy() 调用要求在屏幕上锁定,而 frame.close() 并未释放该锁定。因此,当在第二个场景/测试中对 BasicRobot.robotWithCurrentAwtHierarchy() 进行下一次调用时,调用将阻塞等待锁被释放,并有效地创建死锁。解决方案是使用 robot.cleanUp 手动释放锁(它还会关闭并处理所有打开的窗口)。但是,为什么 frame.close 在关闭最后一帧时不执行此操作超出了我的范围。

例子1

public class CucumberHooks {
private FrameFixture frame;

@Before
public void setup() throws InterruptedException, IOException {
Thread t = new Thread(new Runnable() {
public void run() {
File file = new File(System.getProperty("external-jar"));
URLClassLoader cl = null;
try {
cl = new URLClassLoader( new URL[]{file.toURI().toURL()} );
}
catch (MalformedURLException e) {}

Class<?> clazz = null;
try {
clazz = cl.loadClass("MainClass");
}
catch (ClassNotFoundException e) {}

Method main = null;
try {
main = clazz.getMethod("main", String[].class);
}
catch (NoSuchMethodException e) {}

try {
main.invoke(null, new Object[]{new String[]{}});
}
catch (Exception e) {}
}
});
t.start();

GenericTypeMatcher<JFrame> matcher = new GenericTypeMatcher<JFrame>(JFrame.class) {
protected boolean isMatching(JFrame frame) {
return "External Jar Title".equals(frame.getTitle()) && frame.isShowing();
}
};

frame = WindowFinder.findFrame(matcher).using(BasicRobot.robotWithCurrentAwtHierarchy());
}

@After
public void shutDown() throws InterruptedException {
NoExitSecurityManagerInstaller i = NoExitSecurityManagerInstaller.installNoExitSecurityManager();
frame.close();
i.uninstall();
}
}

例子2

public class CucumberHooks {
private FrameFixture frame;
private Robot robot;

@Before
public void setup() throws InterruptedException, IOException {
Thread t = new Thread(new Runnable() {
public void run() {
File file = new File(System.getProperty("external-jar"));
URLClassLoader cl = null;
try {
cl = new URLClassLoader( new URL[]{file.toURI().toURL()} );
}
catch (MalformedURLException e) {}

Class<?> clazz = null;
try {
clazz = cl.loadClass("MainClass");
}
catch (ClassNotFoundException e) {}

Method main = null;
try {
main = clazz.getMethod("main", String[].class);
}
catch (NoSuchMethodException e) {}

try {
main.invoke(null, new Object[]{new String[]{}});
}
catch (Exception e) {}
}
});
t.start();

GenericTypeMatcher<JFrame> matcher = new GenericTypeMatcher<JFrame>(JFrame.class) {
protected boolean isMatching(JFrame frame) {
return "External Jar Title".equals(frame.getTitle()) && frame.isShowing();
}
};

robot = BasicRobot.robotWithCurrentAwtHierarchy();
frame = WindowFinder.findFrame(matcher).using(robot);
}

@After
public void shutDown() {
robot.cleanUp();
}
}

最佳答案

这只是一个猜测:您必须在启动线程之前安装 NoExitSecurityManagerInstaller。参见 http://docs.codehaus.org/display/FEST/Handling+System.exit

关于java - FEST:启动/停止使用 System.exit() 而不影响 VM 的外部 SWING 程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21258220/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com