Java语言在线编译器的设计与实现
2019-11-16谢伟增金振乾
文/谢伟增 金振乾
各种程序设计课程是高校理工科类学生的必修课程。这些课程不仅使学生的逻辑分析能力、程序设计能力得到训练,还为后续的各种与编程有关的专业课程奠定了学习基础。目前学习程序设计最常用的方式是通过集成开发环境IDE。无论用户使用何种操作系统,都有支持该平台的集成开发环境平台可供使用。诸如Windows平台下有微软公司开发的Visual Studio,MacOS平台下有苹果公司开发的Xcode,另外还有一些跨平台开发环境如Eclipse、Apache NetBeans和IntelliJ IDEA等等。这些IDE集成了编辑、编译和调试等实用且强大的功能,适用于各种桌面环境,但是通常配置也比较复杂,而且往往还有版权方面的限制,使用成本较高。而另一方面,随着移动通信网络的迅猛发展,各种移动通信设备大量普及,无线网络全面覆盖,使得几乎人人都可以通过无线宽带网络随时联网,始终在线。如果把这个途径用于程序设计的实践学习,使学生能够通过智能手机、平板电脑等各种联网设备访问在线编译器平台,就能突破时间、空间的限制,以及软件、硬件方面的约束,充分利用“碎片”时间,通过浏览器访问在线编译器,完成程序的编辑、编译等任务。
在线编译器通常使用浏览器/服务器的工作模式,将程序编译和运行的主要功能放在服务器端,客户端无需安装任何开发环境和编译器软件,直接通过浏览器打开Web页面与服务器进行交互,实现程序编写、编译及执行的全部过程。这样不仅避免了在客户端设备上安装和配置传统编译环境的麻烦,也摆脱了对客户端设备类型和性能的限制。基于这些优点,在线编译器的开发和应用得到不断地扩展。目前已有的在线编译器有多种不同的实现类型,各种类型也都存在一些不足,主要表现在:界面不简洁,支持编程语言种类少;传统的物理服务器在部署、资源分配、可靠性等的不足与限制;编写时无感应显示框,不能高亮显示代码等方面。
因此,我们设计了一个基于Browser/Server模式的在线编译器,在前端页面实现了设备适配,允许用户通过各种网络终端设备访问,在服务器端实现了源程序文档管理、后台编译和前后台信息交互的功能,提供稳定的多用户在线编译服务。
1 开发和运行环境
1.1 开发环境
开发过程中所选择的集成开发环境为JetBrains公司的产品IntelliJ IDEA。作为目前最主流的Java集成开发环境之一,IntelliJ IDEA具备强大的静态代码分析和人机工程学设计,能够显著提高开发人员的生产力,而且还有基于Apache 2.0开放式授权的社区版本可供使用。IntelliJ IDEA原生支持maven,可进行高级项目管理,实现快速开发。在开发环境中完成项目设计和调试以后,将其部署到服务器上就可以正常访问了。
1.2 服务器运行环境
编译服务器是确保在线编译功能得以实现的核心环节,既要具备高度的稳定性和快速的反应能力,又要能够支持大量的并发连接,因此选择以高性能、高稳定性著称的Linux系统,各个主流发行版均可正常运行,如Debian,Ubuntu和CentOS等。应用软件方面,采用成熟的OpenJDK 8,Apache Tomcat 8.5,并使用Maria DB 10作为后台数据库,为提高并发能力,还提高了数据库连接池技术。该配置稳定可靠,成本低廉,性能较好。得益于这些软件的跨平台能力,同样的系统也可以运行在Windows平台上,提高了部署的便捷性。
2 关键技术
在线编译器的应用把编译和运行放到服务器上进行,消除了在客户端设备上安装编译环境的需求。但是要实现在线编译,有两个核心问题必须要解决:一是如何把用户在网页上输入的源程序代码交给服务器进行编译执行;二是如何将程序的运行结果或编译错误信息在网页上输出。针对这些关键问题,我们采用了以下方式来解决。
2.1 动态编译的实现方式
目前常用的Java语言动态编译的实现方案主要有:
(1)使用JavaCompiler接口来实现Java源程序的动态编译。
(2)通过StandardJavaFileManager类实现Java源程序动态编译。
(3)从内存中动态编译Java程序。
这些方式或者缺乏灵活性并效率较低,或者不符合系统需求,或者依赖于某个具体的Java类的版本和方法。因此我们采用了直接生成Runtime对象,并通过Runtime对象生成调用complie命令或run命令的相关进程,实现在服务器端编译和运行Java程序的核心功能。
在调用complie命令或run命令时,先判断服务器端操作系统的类型,然后根据类型构建相应的编译命令行和运行命令行(命令行中还需包含需要执行的Java程序的代码路径及主类名称)。首先通过调用相关方法进行编译操作,编译过程如果发现错误则返回错误信息,如果编译成功则继续调用相关方法进行运行操作,并返回运行结果。核心代码如下所示:
图1:程序代码编辑及运行界面
2.2 编译错误信息和运行结果的输出
在编译和运行Java源程序代码时,可能会产生两种信息,一种是运行结果输出,一种是错误信息输出,需要对这两种信息都进行捕捉。所以在相关的方法中,我们创建了两个输入流,一个用于连接运行结果输出,另一个用于连接错误信息输出。但一般情况下,这两种信息不会同时出现,程序正确执行时会输出运行结果,程序执行失败时会输出错误信息。为了方便处理,我们捕捉这两种信息,但合并到一个字符串对象中一同处理。在运行编译命令时,如果程序没有语法问题,不会有任何信息输出,输入流不会捕捉到任何信息;如果程序有语法问题,会输出编译错误或警告信息,输入流也会捕捉到错误或警告信息。因此,如果编译没有出错,捕捉到的信息对象为空,则可以继续执行运行代码的命令。如果编译出错,则到此结束,将捕捉到的编译错误信息返回页面显示。
3 系统实现
3.1 代码编辑器的实现
为了方便用户直接在Web页面上编辑程序,直接在页面代码中集成了名为CodeMirror的代码编辑器组件。CodeMirror是一个基于MIT授权的开源项目,是基于JavaScript实现的通用文本编辑器,专门用于源代码编辑,并附带了许多能实现高级编辑功能的语言模式和插件,如代码自动补齐、代码着色、代码折叠、快捷键绑定等。为了简化代码并节约服务器资源,程序中仅设置了必要的几项功能和有限的几种主题配色方案。实际上CodeMirror支持超过100种编程语言和许多种主题配色方案,这也为项目将来的功能扩展提供了有力的支撑。
3.2 前端与后台开发
前端开发过程中使用了完全开源的Bootstrap前端开发框架,实现了基本的响应式布局,使得用户注册、登录,源代码编辑等各个页面都能够有效适配手机、平板等各种移动终端设备和PC等桌面终端设备。响应式交互页面具备一般的静态页面所没有的许多优点,既能避免针对不同设备的重复开发,有效节约成本,又能确保显示的内容适应不同的平台和不同的设备,保障用户体验。在线编译器平台本身的功能要求决定了其前端的页面结构设计无需过于复杂,但必须保证在各种终端设备上都能被良好地呈现,因此在线编译器的前端开发也更适合响应式页面。
由于本项目在运行过程中面对的是大批量的学生,每名学生都有可能有多个源程序代码需要管理,因此在后台进行用户认证、用户信息提示以及用户源代码文档处理的时候,我们引入了免费的、基于Apache许可证2.0版本发布的FreeMaker。FreeMaker是一种模版引擎,模版的编写是通过专用的FreeMaker模版语言(FTL)实现的。通过这个引擎,可以在代码中指定模版和需要变动的数据集,然后就可以通过引擎自动生成包含相应数据的文本内容。
图2:移动设备端程序输入界面
3.3 用户界面设计
用户界面是用户与在线编译器进行交互的接口,既要具备必要的功能,又要足够简洁,避免增加用户的学习负担。在线编译器的重点功能是实现源代码的提交和修改,并获得程序的编译错误信息和运行结果。对这些信息的交互和功能的实现做到集中展示和合理布局才能提供更好的用户体验,提高用户使用在线编译器的效率。因此,我们的设计思路是在用户登录到系统之后,所有的源程序选择、源代码编辑、执行编译运行功能、查看运行结果、查看编译错误信息等主要功能都呈现在一个页面中,用户无需在多个页面中来回跳转,也无需频繁刷新页面以显示信息。
这个布局共有三个区域,覆盖了用户的源代码的管理、提交、修改、运行、查看输出结果的所有功能需求。当用户登录到在线编译器系统后,在左侧源代码文件列表区域可显示该用户已经编制过的所有源代码程序列表,通过点击列表中某项,则该项对应的源代码自动呈现到源代码提交/编辑区域,用户可对源代码内容进行审核与编辑;编辑完成后,通过点击“提交运行”按钮,将编辑区域的源代码提交到编译服务器进行保存,然后由服务器端调用相关代码进行编译操作,如果编译不成功,则获取编译错误信息并输出到编译错误信息显示区域;如果编译成功,则继续调用相关代码执行程序并获取程序运行结果,然后将运行结果输出到程序运行结果显示区域。
4 测试实验
4.1 Java程序测试
如图1所示,当以合法用户身份登录以后,在左侧的现有源代码程序列表中选择一个已经存在的源程序,其源代码自动出现在右上侧的源代码编辑区域;图1中所显示的一段完整的Java源程序代码,该程序代码没有任何语法错误,因此当用户点击“提交运行”按钮之后,程序的运行结果将会自动显示在右下侧的程序运行结果显示区域。
4.2 移动设备适应性测试
通过手机、平板电脑等移动设备访问编译服务器,并以合法用户身份登录后,也可以正常进行源代码提交和编辑,并显示程序运行结果或编译错误提示信息等功能。需要注意的是,在移动设备上访问在线编译器的时候,受限于移动设备显示屏幕的面积大小,这些元素无法同时显示在屏幕上,但是可以通过上下滚动的方式进行查看。图2所示的是在手机上进行源代码输入的界面,由于手机屏幕的面积有限,而虚拟键盘又遮挡了小部分屏幕,留给用户的显示面积并不算多,用户能够同时看到的源代码也不多。虽然可以通过滚动的方式显示位于编辑区域各个位置的代码,但是用户体验始终不够完美。因此在移动设备上访问在线编译器应主要以源代码的提交、审阅和微量修改为主,同时辅以程序编译和运行功能的实现,不适宜大量源代码的持续输入。不过由于智能手机等移动设备在学生的学习和生活当中占据了大量的时间,可以以智能手机访问在线编译器进行网络在线编程,对分散的知识点及小规模的程序进行编程验证,然后在实验课上侧重对综合性及创新性的程序进行调试。该模式打破了传统实验室上机实践在时间与空间上的限制,使编程实践贯穿于课程教学的全过程,实现了信息技术与教学的有效融合。这种灵活多样的编程实践环境确实能使学生的编程能力得到提升。
5 结语
在线编译器在计算机编程语言教学过程中有很大的应用需求,根据我们在2018级计算机应用技术专业两个教学班级进行对照教学(一个班级按照常规的教学实践环境进行编程训练,对照班级将常规的教学实践与在线编译器的编程练习相结合)的结果表明,在线编译器的使用能够有效延长学生进行编程训练的时间,在线编程作为常规的集成开发环境编程的有益补充,为学生提供了多样化的编程实践平台,有力提高了学生自主学习的积极性和主动性。
在实践当中我们也发现了这个在线编译器目前存在的一些问题,例如对程序逻辑错误的检测缺乏必要的手段;程序执行过程中缺乏必要的交互;编译错误信息在源代码编辑窗口的定位功能尚未实现。这些问题都会在后续的版本更新中逐步予以解决。将来该系统还可以扩展为在线学习平台,不仅实现在线编译的功能,还能够实现编程作业的提交和审核、平台使用情况数据的采集和统计、学习进度和学习问题反馈、代码分享和编程协作等功能,以更低的成本和更高的灵活性,在编程语言教学领域发挥更大的作用。