- 浏览: 470158 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
chexiazi:
一样的xml代码 报这个错 <ns1:XMLFault ...
CXF 通过用户名和密码进行验证 -
di1984HIT:
谢谢啊 ~~~
通过JavaCompiler进行编译java文件(转载) -
aa00aa00:
'%${userName}%' 这种是可以的,是可以模糊查询的 ...
mybatis 模糊查询 -
一棵杨柳的地盘:
我把你的代码不了一遍 但是汇报错首先:static { ...
CXF 通过用户名和密码进行验证 -
shangmin1990:
转 IntelliJ IDEA 编辑器生成 Hibernate 实体映射文件
通过JavaCompiler进行编译都是在当前目录下生成.class文件,而使用编译选项可以改变这个默认目录。编译选项是一个元素为String类型的Iterable集合。如我们可以使用如下代码在D盘根目录下生成.class文件。
Iterable options = Arrays.asList("-d", "d:\\");
JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager,
diagnostics, options, null, compilationUnits);
06 年底,Sun 公司发布了 Java Standard Edition 6(Java SE 6)的最终正式版,代号 Mustang(野马)。跟 Tiger(Java SE 5)相比,Mustang 在性能方面有了不错的提升。与 Tiger 在 API 库方面的大幅度加强相比,虽然 Mustang 在 API 库方面的新特性显得不太多,但是也提供了许多实用和方便的功能:在脚本,WebService,XML,编译器 API,数据库,JMX,网络和 Instrumentation 方面都有不错的新特性和功能加强。 本系列 文章主要介绍 Java SE 6 在 API 库方面的部分新特性,通过一些例子和讲解,帮助开发者在编程实践当中更好的运用 Java SE 6,提高开发效率。
本文是其中的第四篇,介绍了 JDK 6 中为在运行时操纵编译器所增加的编译器 API(JSR 199)。您将了解到,利用此 API 开发人员可以在运行时调用 Java 编译器,还可以编译非文本形式的 Java 源代码,最后还能够采集编译器的诊断信息。本文将展开描述这些功能,并使用这些功能构造一个简单的应用 —— 在内存中,直接为一个类生成测试用例。
新 API 功能简介
JDK 6 提供了在运行时调用编译器的 API,后面我们将假设把此 API 应用在 JSP 技术中。在传统的 JSP 技术中,服务器处理 JSP 通常需要进行下面 6 个步骤:
分析 JSP 代码;
生成 Java 代码;
将 Java 代码写入存储器;
启动另外一个进程并运行编译器编译 Java 代码;
将类文件写入存储器;
服务器读入类文件并运行;
但如果采用运行时编译,可以同时简化步骤 4 和 5,节约新进程的开销和写入存储器的输出开销,提高系统效率。实际上,在 JDK 5 中,Sun 也提供了调用编译器的编程接口。然而不同的是,老版本的编程接口并不是标准 API 的一部分,而是作为 Sun 的专有实现提供的,而新版则带来了标准化的优点。
新 API 的第二个新特性是可以编译抽象文件,理论上是任何形式的对象 —— 只要该对象实现了特定的接口。有了这个特性,上述例子中的步骤 3 也可以省略。整个 JSP 的编译运行在一个进程中完成,同时消除额外的输入输出操作。
第三个新特性是可以收集编译时的诊断信息。作为对前两个新特性的补充,它可以使开发人员轻松的输出必要的编译错误或者是警告信息,从而省去了很多重定向的麻烦。
运行时编译 Java 文件
在 JDK 6 中,类库通过 javax.tools 包提供了程序运行时调用编译器的 API。从这个包的名字 tools 可以看出,这个开发包提供的功能并不仅仅限于编译器。工具还包括 javah、jar、pack200 等,它们都是 JDK 提供的命令行工具。这个开发包希望通过实现一个统一的接口,可以在运行时调用这些工具。在 JDK 6 中,编译器被给予了特别的重视。针对编译器,JDK 设计了两个接口,分别是 JavaCompiler和 JavaCompiler.CompilationTask。
下面给出一个例子,展示如何在运行时调用编译器。
指定编译文件名称(该文件必须在 CLASSPATH 中可以找到):String fullQuanlifiedFileName = "compile" + java.io.File.separator +"Target.java";
获得编译器对象: JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
通过调用 ToolProvider 的 getSystemJavaCompiler 方法,JDK 提供了将当前平台的编译器映射到内存中的一个对象。这样使用者可以在运行时操纵编译器。JavaCompiler 是一个接口,它继承了javax.tools.Tool 接口。因此,第三方实现的编译器,只要符合规范就能通过统一的接口调用。同时,tools 开发包希望对所有的工具提供统一的运行时调用接口。相信将来,ToolProvider 类将会为更多地工具提供 getSystemXXXTool 方法。tools 开发包实际为多种不同工具、不同实现的共存提供了框架。
编译文件:int result = compiler.run(null, null, null, fileToCompile);
获得编译器对象之后,可以调用 Tool.run 方法对源文件进行编译。Run 方法的前三个参数,分别可以用来重定向标准输入、标准输出和标准错误输出,null 值表示使用默认值。清单 1 给出了一个完整的例子:
清单 1. 程序运行时编译文件
01 package compile;
02 import java.util.Date;
03 public class Target {
04 public void doSomething(){
05 Date date = new Date(10, 3, 3);
// 这个构造函数被标记为deprecated, 编译时会
// 向错误输出输出信息。
06 System.out.println("Doing...");
07 }
08 }
09 package compile;
10 import javax.tools.*;
11 import java.io.FileOutputStream;
12 public class Compiler {
13 public static void main(String[] args) throws Exception{
14 String fullQuanlifiedFileName = "compile" + java.io.File.separator +
"Target.java";
15 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
16 FileOutputStream err = new FileOutputStream("err.txt");
17 int compilationResult = compiler.run(null, null, err, fullQuanlifiedFileName);
18 if(compilationResult == 0){
19 System.out.println("Done");
20 } else {
21 System.out.println("Fail");
22 }
23 }
24 }
首先运行 <JDK60_INSTALLATION_DIR>\bin\javac Compiler.java,然后运行 <JDK60_INSTALLATION_DIR>\jdk1.6.0\bin\java compile.Compiler。屏幕上将输出 Done ,并会在当前目录生成一个 err.txt 文件,文件内容如下:
Note: compile/Target.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
仔细观察 run 方法,可以发现最后一个参数是 String...arguments,是一个变长的字符串数组。它的实际作用是接受传递给 javac 的参数。假设要编译 Target.java 文件,并显示编译过程中的详细信息。命令行为:javac Target.java -verbose。相应的可以将 17 句改为:
int compilationResult = compiler.run(null, null, err, “-verbose”,fullQuanlifiedFileName);
编译非文本形式的文件
JDK 6 的编译器 API 的另外一个强大之处在于,它可以编译的源文件的形式并不局限于文本文件。JavaCompiler 类依靠文件管理服务可以编译多种形式的源文件。比如直接由内存中的字符串构造的文件,或者是从数据库中取出的文件。这种服务是由 JavaFileManager 类提供的。通常的编译过程分为以下几个步骤:
解析 javac 的参数;
在 source path 和/或 CLASSPATH 中查找源文件或者 jar 包;
处理输入,输出文件;
在这个过程中,JavaFileManager 类可以起到创建输出文件,读入并缓存输出文件的作用。由于它可以读入并缓存输入文件,这就使得读入各种形式的输入文件成为可能。JDK 提供的命令行工具,处理机制也大致相似,在未来的版本中,其它的工具处理各种形式的源文件也成为可能。为此,新的 JDK 定义了 javax.tools.FileObject 和 javax.tools.JavaFileObject 接口。任何类,只要实现了这个接口,就可以被 JavaFileManager 识别。
如果要使用 JavaFileManager,就必须构造 CompilationTask。JDK 6 提供了 JavaCompiler.CompilationTask 类来封装一个编译操作。这个类可以通过:
JavaCompiler.getTask (
Writer out,
JavaFileManager fileManager,
DiagnosticListener<? super JavaFileObject> diagnosticListener,
Iterable<String> options,
Iterable<String> classes,
Iterable<? extends JavaFileObject> compilationUnits
)
方法得到。关于每个参数的含义,请参见 JDK 文档。传递不同的参数,会得到不同的 CompilationTask。通过构造这个类,一个编译过程可以被分成多步。进一步,CompilationTask 提供了setProcessors(Iterable<? extends Processor>processors) 方法,用户可以制定处理 annotation 的处理器。图 1 展示了通过 CompilationTask 进行编译的过程:
图 1. 使用 CompilationTask 进行编译
JDK 6 的编译器新特性,使得开发者可以更自如的控制编译的过程,这给了工具开发者更加灵活的自由度。通过 API 的调用完成编译操作的特性,使得开发者可以更方便、高效地将编译变为软件系统运行时的服务。而编译更广泛形式的源代码,则为整合更多的数据源及功能提供了强大的支持。相信随着 JDK 的不断完善,更多的工具将具有 API 支持,我们拭目以待。
- dynamic.rar (1.7 KB)
- 下载次数: 22
发表评论
-
java 位运算总结
2018-10-23 11:14 0<div class="iteye-blog- ... -
java sort 排序中的自然序排序总结
2018-10-23 11:07 5816<div class="iteye-blo ... -
Java内存分析工具
2012-11-24 11:16 2254Java运行时数据区包含:Method area, heap, ... -
转 StringUtils.isBlank()函数(分享一下)
2012-02-15 10:23 2987StringUtils的isBlank与isEmply ... -
jquery 使用ajax 提交整个表单的数据
2012-01-06 14:52 5918在使用Struts开发项目的时候发现很爽的一件事就是可以不使用 ... -
struts2 通配符
2011-12-31 16:25 1286在使用struts2时,如果想定义action的话可以这样做 ... -
Maven Web项目部署到Tomcat下
2011-12-30 17:28 19547通过Maven来搭建项目是 ... -
velocity与servlet的整合
2011-12-28 21:07 1458第一天学习velocity,参考别人的blog写了一个与Se ... -
ibatis 与spring3整合
2011-12-28 13:01 5729spring与ibates整合,使用 ... -
ibatis 入门
2011-12-28 12:48 1271昨天学习了一下ibatis ... -
转 JTA简介
2011-12-26 17:47 1062Java Transaction API(Java事务 ... -
转 IntelliJ IDEA 编辑器生成 Hibernate 实体映射文件
2011-12-23 16:03 23388很多人不知道怎么用 IntelliJ IDEA 编辑器 ... -
转 IntelliJ IDEA 使用基础篇 Java IDE编辑器
2011-12-23 15:02 8520IntelliJ IDE ... -
转在CXF中用JAXB数据绑定支持Map类型
2011-12-05 16:38 5231一些java类型不能自然映射成xml,例如,HashMap ... -
cxf wsdltojava 构造方法报错
2011-12-05 14:23 1323I'm marking this as "n ... -
(转)Struts2学习笔记--Internationalization
2011-11-21 18:13 1333Struts2 的国际化 ======== ... -
单例模式
2011-11-18 20:47 1015单例模式(SINGLETON):单例模式确保某一个类只有一个实 ... -
类加载的顺序
2011-11-17 21:40 1191写道 package com.wang; public cl ... -
socket实现客户端与客户端通信
2011-11-17 19:34 3043最近闲来无聊,看了一下socket通信,实现了一个最简版的客户 ... -
接口设计的 11 种原则
2011-05-02 21:02 27437种设计坏味道 1.僵化性: 很难对系统进行改动,因为每个改动 ...
相关推荐
* JavaCompiler 的 run 方法可以传入多个 Java 源代码文件,以便同时编译多个文件。 除了使用 JavaCompiler 接口之外,我们还可以使用 StandardJavaFileManager 来编译 Java 源代码。StandardJavaFileManager 是 ...
Java反编译工具是开发者和逆向工程人员用于查看Java字节码的工具,以便理解已编译的Java类文件中的源代码逻辑。在Java生态系统中,这些工具扮演着重要的角色,因为Java的源代码通常不会随二进制类文件一起发布。本文...
通过自定义ClassLoader和利用`JavaCompiler` API,我们可以实现Java源文件的动态编译和加载,从而实现程序运行时的灵活扩展。在实际应用中,我们需要注意类加载的性能影响,以及类加载器之间的隔离问题,以确保系统...
Java反编译是将已编译的字节码(.class文件)转换回源代码(.java文件)的过程,这对于理解和学习已有的Java程序、逆向工程或调试都是很有用的。标题提到的"java反编译工具"是用于这个目的的软件,它能够帮助开发者...
**** JavaCompiler欢迎使用JavaCompiler ! 此java编译器将java文件编译为dex文件。 将Java文件/ jar文件转换为dex 语言支持:中文,英文。 支持lib文件(修复bug)
创建一个`Iterable`对象,包含要编译的.java文件。假设我们有一个名为`MyClass.java`的文件,我们可以这样设置: ```java File sourceFile = new File("MyClass.java"); Iterable<? extends File> ...
1、打开一个或者多个*.class文件,XJad反编译后,重命名为*.java文件, 保存至当前文件夹,并在编辑器中打开查看; 2、打开一个文件夹,XJad将该文件夹下所有*.class文件进行反编译,并保存至该文件夹下, 依据包...
Java反编译工具和文件比较工具是开发过程中非常重要的辅助软件。它们在代码分析、调试和版本控制中扮演着关键角色。以下是对这两个主题的详细解释: **Java反编译工具** Java反编译工具主要用于将已编译的Java字节...
在IT行业中,开发人员经常会遇到需要对已有的jar包或class文件进行反编译和调试的情况,以便理解其内部逻辑或修复bug。Eclipse作为一款流行的Java集成开发环境(IDE),提供了丰富的插件支持,使得这个过程变得相对...
### Java反编译工具:将.class文件转换为.java文件 #### 概述 在软件开发领域,有时我们可能需要分析第三方库或者开源项目的内部结构,这时就需要借助于反编译工具来帮助我们阅读和理解其源码。Java作为一种广泛...
Java反编译是一种技术,它允许开发者从已编译的.class文件中恢复原始的.java源代码。这在一些情况下非常有用,例如分析第三方库的内部实现、研究代码逻辑或者在丢失源代码时恢复源码。Java编译器将源代码转换成字节...
Java开发过程中,有时我们需要查看或理解已编译的Class文件中的源代码,因为Java的编译过程会将源代码转化为字节码(.class文件)。在这种情况下,反编译工具就派上了用场。本篇文章将详细介绍Java的jar反编译工具...
在Java开发过程中,有时我们需要查看或分析已编译的.class文件中的源代码,这就涉及到Java的反编译技术。...通过上述方法,开发者可以更顺利地进行Java反编译工作,即便遇到中文字符也能得到清晰的源代码。
如果需要,可以通过“File”菜单选择“Save As...”选项将反编译的源代码保存为.java文件。 在实际开发中,反编译工具主要用于以下情况: - **学习与研究**:当没有源代码时,可以通过反编译了解库或框架的工作...
接着,我们将要编译的.java文件转换为`JavaFileObject`,并调用`compiler.compile()`进行编译。 编译完成后,我们可以使用`ClassLoader`来动态加载并运行新编译的类。以下是如何加载并执行一个名为`MyClass`的类: ...
Java Class文件是Java程序编译后的二进制格式,它包含了类和接口的定义、方法体、常量池等信息,但这些信息是以机器可读的字节码形式存在,对于人类来说不易理解。为了查看和理解Class文件内部的源代码,我们就需要...
JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA反编译工具JAVA...
Java反编译exe主要指的是将Java的字节码(.class文件)转换回源代码(.java文件)的过程。在Java编程中,源代码被编译成字节码,然后由JVM(Java虚拟机)执行。然而,出于调试、学习或者逆向工程的目的,有时我们...
在编写完Java源代码(.java文件)后,我们需要使用javac编译器将其转化为字节码(.class文件)。例如,如果你有一个名为`Main.java`的源文件,你可以通过以下命令进行编译: ``` javac Main.java ``` 这将在同一...