0

我有一个大型桌面 Java 应用程序正在从 JRE 1.6 迁移到 JRE 1.7。该应用程序使用用于 GUI 的 NetBeans API 和带有 Log4J 后端的 SLF4J API。该应用程序有两种部署方法,一个独立的应用程序(由 Ant 或 Launch4j exe 运行)或通过简单的自定义 HTTP 服务器(Jetty 和 JNLP servlet)进行 Web 启动。

该应用程序有几个 NetBeans ModuleInstall 组件,它们在启动时将属性编辑器添加到 Java PropertyEditorManager 搜索路径中。例如

ArrayList<String> editorPaths = new ArrayList<String>();
editorPaths.add(LocationEditor.class.getPackage().getName());
editorPaths.addAll(Arrays.asList(PropertyEditorManager.getEditorSearchPath()));
PropertyEditorManager.setEditorSearchPath(editorPaths.toArray(new String[editorPaths.size()]));

当我迁移到 Java 1.7 (u9) 时,这些编辑器不再出现在应用程序中,无论是独立部署还是 Web 启动部署。应用程序启动良好,从 Eclipse 启动时可以访问编辑器。想知道独立失败的原因,我添加了一些日志记录语句来报告搜索路径并通过 Ant 启动脚本设置log4j.configuration属性。编辑器现在可用。然后我启动了 .exe(它不接受命令行参数,因此未设置 log4j 配置),编辑器又消失了。

因此,差异化因素似乎是设置 log4j.configuration 参数。我更改了构建,因此standlong Ant 和 .exe 引用了它并且它们可以工作。虽然网络启动并没有传递这个值(它在代码内部加载)并且仍然无法找到编辑器。我还从 Eclipse 运行命令中删除了 log4j 设置,编辑器再次消失。

我尝试专门针对类型注册,而不是使用搜索路径,但仍然没有成功。我使用搜索路径作为一个可选的覆盖另一个模块编辑器,但我不知道模块启动顺序,因此一个将其路径附加到查找的开头,而其他的则附加到末尾。

我还尝试删除所有 SLF4J 到 Log4J 的映射并改用 SLF4J-Simple。这没什么区别。重新添加参数会使代码再次工作。spring-aspects 依赖项引入了一个 Log4J 引用。

我有一个独立的工作解决方案,我确信我可以让这个新技巧适用于 webstart,但这听起来像是一个糟糕的黑客让事情正常工作。我宁愿找出编辑失踪的原因。不会报告任何异常,并且从所有 ModuleInstall 对象中删除日志不会执行任何操作。所有代码仍在执行,这包括 ModuleInstall 执行的其他功能,因此我知道它们正在运行。

我正在使用 NetBeans RELEASE72,其他依赖项是:

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>1.7.2</version>
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
  <version>1.7.2</version>
</dependency>

更新 1

我已将问题追溯到我们的自定义日志记录设置。当此部分被删除并使用简单的记录器时,问题没有发生。当这个自定义配置被删除并且 slf4j-log4j12 再次连接时,我仍然得到了属性编辑器。但是,当我再次启用自定义日志记录配置时,编辑器失败了。

即使用户未指定任何内容,自定义日志记录配置也可确保我们进行日志记录设置。还有一些其他用户激活的奇怪的启动过程,在编织过程之后才能激活日志记录。我怀疑自定义日志记录设置可能不适用于 Java 1.7,或者与替换默认日志记录处理程序重定向到我们的自定义日志记录有关。

无论如何,它看起来像是一个内部混乱,互联网无能为力。

4

2 回答 2

1

我已经离开了这个问题,最后又回到了它。问题是 PropertyEditorManager 现在不再是全局单例,而是线程本地单例。搜索路径在 JDK 1.7 的 ThreadLocalContext 中注册,大概是为了防止线程同步问题。然而,NetBeans ModuleInstall 在主线程上执行,然后在 AWT 线程上读取属性读取器。这意味着 AWT 线程没有找到任何属性编辑器。

作为修复,我只是使用 SwingUtilities.invokeLater() 来注册属性编辑器路径。

我不知道是什么导致其他症状出现。

于 2013-04-09T11:36:27.167 回答
1

我一直在追踪一个类似的问题;当我在 java 1.7.0_25 下运行我的 NetBeans RCP 7.3 应用程序时 org.netbeans.beaninfo.editors.DateEditor,我的 GUI 属性表不再可用。

正如你所建议的,我通过将此代码包含到我的 GUI 模块的安装程序中来解决这个问题

SwingUtilities.invokeLater(new Runnable()
{
    @Override
    public void run() {
        NodeOp.registerPropertyEditors();
    }
});

这暂时解决了问题,但感觉有点hacky......

于 2013-07-31T13:43:14.530 回答