我参与了一个需要通过 web 运行并可以访问 java 的编译器工具和/或 javacc api 的项目。我的团队正在考虑使用 Java 小程序使其基于 Web。我想知道在这种情况下小程序可以做什么和不能做什么有某些限制。我会假设因为对编译器的访问将在服务器上完成,而不是在客户端的机器上,所以这不会是一个问题。小程序是否允许我们按照描述将两者分开?
2 回答
是的,applet 可以访问它们,这可能是一个不错的选择。但它的外观和感觉非常有限/沉闷。在此使用 JavaFx,您可以定义自己的 StyleSheet,这样它会给您一个非常好的外观和感觉,是的,它肯定也会将两层分开。
如果 applet 已签名,则 applet(甚至 JavaFX applet)可以在这种情况下工作。小程序存在许多微妙的陷阱,因此我建议在使用该技术之前进行原型设计。按照JavaFX 部署指南了解如何部署基于 JavaFX 的小程序。
我曾认为要编译 Java,您需要安装完整的 Java 开发工具包(这在小程序部署情况下很难确保)。但似乎编译 API 包含在标准 Java 运行时环境中包含的javax.tools API 中。因此,这可能意味着您可以开发您的解决方案,包括基于客户端的 Java 代码部署和编译,而无需用户安装完整的 Java 开发工具包。
您可能还希望考虑一个客户端/服务器解决方案,其中可以在服务器上执行编译。TopCoder Algorithm Competition Application就是这种方法的一个示例(使用基于 Java WebStart 的解决方案)。这是运行此应用程序的 jnlp 文件 ( http://apps.topcoder.com/wiki/display/tc/The+Algorithm+Competition+Arena )。我建议您使用该应用程序在 TopCoder 注册一个 ID,并尝试使用它编写和编译一些代码。TopCoder 实现使用在 JavaFX 存在之前编写的普通 Swing,但如果您愿意,您同样可以使用 JavaFX 来实现。
如果您还需要一个编辑器(具有语法感知文本样式)来编译您将要编译的代码,您可以使用嵌入在 JavaFX 中的基于CodeMirror的编辑器。基于 CodeMirror 的解决方案将编辑器包装在基于 html 的WebView
控件中。对于 JavaFX 8,您可能可以将新TextFlow
控件用于语法高亮文本编辑器,但该 API 还不是受支持的公共版本的一部分。
更新
我使用此答案中概述的策略完成了这项工作。
该图像是一个 html 页面,允许作为 applet 或 webstart 应用程序访问客户端代码编辑器。图像的顶部区域是代码编辑区域,该区域基于 WebEngine,具有嵌入式语法高亮 CodeMirror JavaScript 编辑器,支持 Java 编辑。图像的底部区域是在客户端计算机上本地编译编辑器中的代码并随后运行它的输出。输出包括任何编译错误、到 sysout 的任何程序输出以及打印到 syserr 的任何运行时异常。解决方案的棘手部分是:
- 研究如何捕获 sysout 和 syserr 并将它们重定向到 JavaFX 控件。
- 查找 Java 编译器。
默认的 Oracle Java 运行时环境提供程序仅提供 Java 编译器实现的通用接口,但它本身不提供 Java 编译器实现 - 该实现仅包含在 jdk 随附的 tools.jar 中。所以当我打包我的applet 时,我在applet 的打包中包含了tools.jar。我在获取服务提供者接口以获取 javac 编译器的实例时遇到了一些困难,所以最后,我只是使用以下行对其进行了实例化:
JavaCompiler compiler = new com.sun.tools.javac.api.JavacTool();
以上内容有些脆弱,因为 sun 可能随时更改其私有 com.sun 类 - 但至少它在这种情况下有效。
要注意的另一件事是,如果您使用 javac 编译器发布 tools.jar,该编译器早于您的系统可用的运行时环境,那么您可能会收到一些警告,如下所示:
warning: C:\Program Files\Java\jre8\lib\rt.jar(java/lang/Object.class): major version 52 is newer than 51, the highest major version supported by this compiler.
It is recommended that the compiler be upgraded.
出现上述警告是因为我使用 java 7 tools.jar 发布了 applet,并使用 java 8 运行时运行了 applet(请注意,无论这些警告如何,applet 都可以正常工作)。
更新
我将此解决方案的代码放在github 存储库中(项目名称概念)。更新后的解决方案使用Eclipse Compiler for Java而不是 Oracle Java Compiler。主要是因为,对于 Eclipse 编译器,它是一个单独的 jar(只有 1.8meg 而不是 oracle 发行版的 14meg 工具 jar)并且许可更清晰一些。因为 Java 编译器接口是可插入的,所以如果将 tools.jar 放在类路径中,Oracle 编译器仍然可以使用。