OpenJML 获取

下载

OpenJML下载可以通过其github仓库获取。传送门

使用

下载完成后,可以直接使用命令行进行操作,但是比较麻烦。这里提供两个版本的辅助文件简化操作

Linux

# filename : openjml
#!/bin/bash
java -jar path/to/openjml.jar "$@"

其中jar包的路径需要自行修改。

Windows

::openjml.bat
@echo off set java=java -jar "%~dp0openjml.jar" -noPurityCheck
set prove=-prover cvc4 -exec "%~dp0Solvers-windows\cvc4-1.6.exe"
set runtime=-cp %~dp0jmlruntime.jar; set allparam=
set rac= :param
set str=%1
if "%str%"=="" (
goto end
)
if "%str%"=="-rac" (
set rac=rac
)
if "%str%"=="-prove" (
set str=%prove%
)
set allparam=%allparam% %str%
shift /0
goto param :end
if "%allparam%"=="" (
goto eof
) rem remove left right blank
:intercept_left
if "%allparam:~0,1%"==" " set "allparam=%allparam:~1%"&goto intercept_left :intercept_right
if "%allparam:~-1%"==" " set "allparam=%allparam:~0,-1%"&goto intercept_right :eof
%java% %allparam%
set filename=
if "%rac%"=="rac" (
:input
set /p filename=Input file name:
if "%filename%"=="" (
goto input
)
java %runtime% %filename%
) pause

用户可以将上述代码拷贝到解压后的文件夹中,然后将该文件夹加入环境变量。即可通过命令行调用openjml命令了。这里为了简化验证时的参数传递,提供了一个-prove参数。用户指定这一参数后,程序将选定prover并执行。

Parsing and Type-checking

OpenJML最基本的功能就是对JML注释的完整性进行检查。检查包括经典的类型检查、变量可见性与可写性等。通过命令行使用OpenJML时,可以通过-check参数(缺省)指定类型检查。

openjml [-check] options files

举例来说

public class main {
/*@
@ require args != null
@*/
public static void main(String[] args) {
System.out.println(args);
}
}

运行语法检查后报错

C:\>openjml main.java
main.java:17: 错误: 需要';'
@ require args != null
^
main.java:17: 错误: 找不到符号
@ require args != null
^
符号: 类 require
位置: 类 main
2 个错误

类型检查检测出了注释中的两处错误。分别更改后的程序如下

public class main {
/*@
@ requires args != null;
@*/
public static void main(String[] args) {
System.out.println(args);
}
}

再次运行后即可通过检查。

Extended Static Checking

类型检查只能确保jml注释的格式正确,但是对规格内容不进行检查。下述程序中明显违背了规格的描述,但是类型检查仍然通过了。

public class main {
/*@
@ requires a != 0 && b != 0;
@ ensures \result <= 1 && \result >= 0;
@*/
public static int fun(int a, int b) {
return a > b ? 1 : 0;
}
public static void main(String[] args) {
fun(1, 0);
}
}

为了对规格内容进行检查,需要使用-esc参数

C:\>openjml -esc -prove main.java
main.java:10: 警告: The prover cannot establish an assertion (Precondition: main.java:6: 注: ) in method main
fun(1, 0);
^
main.java:6: 警告: Associated declaration: main.java:10: 注:
public static int fun(int a, int b) {
^
main.java:3: 警告: Precondition conjunct is false: b != 0
@ requires a != 0 && b != 0;
^
3 个警告

这里需要注意,静态检查需要指定prover。在上述Windows版的批处理函数中,默认指定了一个prover。用户也可以使用-prover等参数指定自定义检查器。

那么esc是如何完成的呢?好奇的话可以通过-progress参数或-verboseness参数来查看检查的具体过程。下面截取了部分输出

C:\>openjml -esc -prove main.java -verboseness=3
...
STARTING PROOF OF main.main(java.lang.String[])
/*@
public behavior
requires args != null;
signals_only java.lang.RuntimeException;
assignable \everything;
accessible \everything;
*/ {
fun(1, 0);
}
...

可以看出OpenJML在验证前会首先重整规格,而后针对性生成测试程序。由于生成程序过长,可以在本地尝试。此处使用的是-verboseness=3,如果使用 4 将会输出大量信息。

Runtime Assertion Checking

使用-rac选项可以执行运行时检查。上述批处理文件中存在 bug,第一次输入文件名时可能会要求再次输入。

C:\>openjml -rac main.java
Input file name:main
main.java:10: 警告: JML precondition is false
fun(1, 0);
^
main.java:6: 警告: Associated declaration: main.java:10: 注:
public static int fun(int a, int b) {
^

这时会自动运行生成出来的.class文件,但经过反汇编后我的.class文件并不能编译。因此目前还没有看懂rac的具体流程。此外,-rac选项有许多补充选项,功能十分丰富,大家可以多多尝试。

参考

OpenJML 基本使用 伦泽标

OpenJML入门的更多相关文章

  1. BUAA OO 2019 第三单元作业总结

    目录 总 JML规格化设计 理论基础 工具链 规格验证 验证代码 代码静态检查 自动生成测试样例 生成结果 错误分析 作业设计 第九次作业 架构 代码实现 第十次作业 架构 代码实现 第十一次作业 架 ...

  2. Angular2入门系列教程7-HTTP(一)-使用Angular2自带的http进行网络请求

    上一篇:Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数 感觉这篇不是很好写,因为涉及到网络请求,如果采用真实的网络请求,这个例子大家拿到手估计还要自己写一个web ...

  3. ABP入门系列(1)——学习Abp框架之实操演练

    作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...

  4. Oracle分析函数入门

    一.Oracle分析函数入门 分析函数是什么?分析函数是Oracle专门用于解决复杂报表统计需求的功能强大的函数,它可以在数据中进行分组然后计算基于组的某种统计值,并且每一组的每一行都可以返回一个统计 ...

  5. Angular2入门系列教程6-路由(二)-使用多层级路由并在在路由中传递复杂参数

    上一篇:Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数 之前介绍了简单的路由以及传参,这篇文章我们将要学习复杂一些的路由以及传递其他附加参数.一个好的路由系统可以使我们 ...

  6. Angular2入门系列教程5-路由(一)-使用简单的路由并在在路由中传递参数

    上一篇:Angular2入门系列教程-服务 上一篇文章我们将Angular2的数据服务分离出来,学习了Angular2的依赖注入,这篇文章我们将要学习Angualr2的路由 为了编写样式方便,我们这篇 ...

  7. Angular2入门系列教程4-服务

    上一篇文章 Angular2入门系列教程-多个组件,主从关系 在编程中,我们通常会将数据提供单独分离出来,以免在编写程序的过程中反复复制粘贴数据请求的代码 Angular2中提供了依赖注入的概念,使得 ...

  8. wepack+sass+vue 入门教程(三)

    十一.安装sass文件转换为css需要的相关依赖包 npm install --save-dev sass-loader style-loader css-loader loader的作用是辅助web ...

  9. wepack+sass+vue 入门教程(二)

    六.新建webpack配置文件 webpack.config.js 文件整体框架内容如下,后续会详细说明每个配置项的配置 webpack.config.js直接放在项目demo目录下 module.e ...

随机推荐

  1. 第06组 Alpha冲刺(4/6)

    队名:拾光组 组长博客链接 作业博客链接 团队项目情况 燃尽图(组内共享) 组长:宋奕 过去两天完成了哪些任务 主要完成了用户联系模块的接口设计 完善后端的信息处理 GitHub签入记录 接下来的计划 ...

  2. Fabric.js canvas 图形库

    1.github地址: https://github.com/fabricjs/fabric.js 2.简述 Fabric.js将canvas的编程变得简单.同时在canvas上添加了交互.交互包括: ...

  3. axios 文件下载代码 片段

    <script type="text/javascript"> axios({ method:'post', url: 'url', // 最好qs.stringify ...

  4. Research Guide for Neural Architecture Search

    Research Guide for Neural Architecture Search 2019-09-19 09:29:04 This blog is from: https://heartbe ...

  5. Weblogic部署web项目获取项目根目录为null

    写在前面 图片上传功能, web项目部署在本地Tomcat上并没有问题, 但是打成war包部署到Linux服务器Weblogic下却出现如题问题, 导致图片上传失败. 问题代码 String real ...

  6. Mysql的utf8与utf8mb4区别,utf8mb4_bin、utf8mb4_general_ci、utf8mb4_unicode_ci区别

    UTF-8是使用1~4个字节,一种变长的编码格式,字符编码.mb4即 most bytes 4,使用4个字节来表示完整的UTF-8. mysql的 utf8 编码最大字符长度为 3 字节,如果遇到 4 ...

  7. JS高级:面向对象解析

    1 实例属性/方法 都是绑定在使用构造函数创建出来的对象p上; 最终使用的时候也是使用对象p来进行访问; function Person(name, age, doFunc) { this.name ...

  8. Servlet2.5版本和Servlet3.0版本

    在学习这节之前你需要在你自己的电脑进行如下配置: 配置Java运行环境:JDK+JRE的安装配置,参考博客Windows下配置Java开发环境: 安装Eclipse:参考博客Windows下配置Jav ...

  9. [计算机视觉][神经网络与深度学习]R-FCN、SSD、YOLO2、faster-rcnn和labelImg实验笔记

    R-FCN.SSD.YOLO2.faster-rcnn和labelImg实验笔记 转自:https://ask.julyedu.com/question/7490 R-FCN paper:https: ...

  10. 手贱重置了mysql密码,导致登陆不进去的解决办法

    上午手残,重置了下MySQL的密码,导致用命令登陆不进去 由于版本的问题,导致网上的方法都不可用 折腾了一上午,摸索+参考官方文档,终于搞定 利用--init-file 第一步,关掉系统服务     ...