`
wuyuhou
  • 浏览: 13938 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

Jdk6中的源代码编译功能

    博客分类:
  • java
阅读更多
JDK6中的源代码编译功能,网上给的示例一般都无法运行,会抛出ClassNotFoundException。
经过改良,主要原因是字节码输出的文件不对。现修改为输出到内存中。
/**
 * 字符串变为Class
 * 
 * @author wuyuhou
 * 
 */
public class StringToClass {
	
	public static void main(String[] args) throws Exception {
		Class clazz = loadClass("com.test.CalculatorTest", 
				"package com.test;"
				+ "public class CalculatorTest {"
				+ "   public int multiply(int multiplicand, int multiplier) {" 
				+ "     System.out.print(multiplicand + \" * \");" 
				+ "     System.out.print(multiplier + \" = \");"
				+ "     return multiplicand * multiplier;" 
				+ "   }" 
				+ "}", StringToClass.class.getClassLoader());
		Object instance = clazz.newInstance();
		Method m = clazz.getMethod("multiply", new Class[] {
				int.class, int.class
		});
		Object[] o = new Object[] {
				3, 2
		};
		System.out.println(m.invoke(instance, o));
	}

	public static Class loadClass(String className, String javaSource, ClassLoader loader) throws ClassNotFoundException {
		JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
		//源码Java对象
		JavaFileObject sourceFileObject = new SimpleJavaFileObjectWrapper(className, Kind.SOURCE, javaSource, null);
		
		//输出到内存中
		ByteArrayOutputStream byteArrayOutput = new ByteArrayOutputStream();
		//Class输出Java对象
		JavaFileObject outputFileObject = new SimpleJavaFileObjectWrapper(className, Kind.CLASS, null, byteArrayOutput);
		
		Iterable<JavaFileObject> files = Arrays.asList(sourceFileObject);
		StandardJavaFileManager fileManager = new StandardJavaFileManagerWrapper(compiler.getStandardFileManager(null, null, null), outputFileObject);
		JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, null, null, files);
		task.call();
		//字节码数组
		byte[] classBytes = byteArrayOutput.toByteArray();
		return new SimpleClassLoader(loader).loadClass(classBytes);
	}
	
	private static class SimpleClassLoader extends ClassLoader {
		public SimpleClassLoader(ClassLoader parent) {
			super(parent);
		}
		public Class<?> loadClass(byte[] classBytes) throws ClassNotFoundException {
			return defineClass(null, classBytes, 0, classBytes.length);
		}
	}
	
	private static class SimpleJavaFileObjectWrapper extends SimpleJavaFileObject {
		
		private String javaSource = null;
		private ByteArrayOutputStream byteArrayOutput = null;
		public SimpleJavaFileObjectWrapper(String className, Kind kind, String javaSource, ByteArrayOutputStream byteArrayOutput) {
			super(URI.create("string:///" + className.replace('.', '/') + kind.extension), kind);
			this.javaSource = javaSource;
			this.byteArrayOutput = byteArrayOutput;
		}
		
		@Override
		public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
			return javaSource;
		}
		
		@Override
		public OutputStream openOutputStream() throws IOException {
			return byteArrayOutput;
		}
	}

	private static class StandardJavaFileManagerWrapper implements StandardJavaFileManager {
		private StandardJavaFileManager defaultWrapper = null;

		private JavaFileObject outputFileObject = null;

		public StandardJavaFileManagerWrapper(StandardJavaFileManager defaultWrapper, JavaFileObject outputFileObject) {
			this.defaultWrapper = defaultWrapper;
			this.outputFileObject = outputFileObject;
		}

		public ClassLoader getClassLoader(Location location) {
			return defaultWrapper.getClassLoader(location);
		}

		public Iterable<JavaFileObject> list(Location location, String packageName, Set<Kind> kinds, boolean recurse) throws IOException {
			return defaultWrapper.list(location, packageName, kinds, recurse);
		}

		public String inferBinaryName(Location location, JavaFileObject file) {
			return defaultWrapper.inferBinaryName(location, file);
		}

		public boolean handleOption(String current, Iterator<String> remaining) {
			return defaultWrapper.handleOption(current, remaining);
		}

		public boolean hasLocation(Location location) {
			return defaultWrapper.hasLocation(location);
		}

		public JavaFileObject getJavaFileForInput(Location location, String className, Kind kind) throws IOException {
			return defaultWrapper.getJavaFileForInput(location, className, kind);
		}

		// 输出重新定位,否则就会报出ClassNotFoundException
		public JavaFileObject getJavaFileForOutput(Location location, String className, Kind kind, FileObject sibling) throws IOException {
			if (outputFileObject != null) {
				return outputFileObject;
			}
			return defaultWrapper.getJavaFileForOutput(location, className, kind, sibling);
		}

		public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException {
			return defaultWrapper.getFileForInput(location, packageName, relativeName);
		}

		public FileObject getFileForOutput(Location location, String packageName, String relativeName, FileObject sibling) throws IOException {
			return defaultWrapper.getFileForOutput(location, packageName, relativeName, sibling);
		}

		public void flush() throws IOException {
			defaultWrapper.flush();
		}

		public void close() throws IOException {
			defaultWrapper.close();
		}

		public int isSupportedOption(String option) {
			return defaultWrapper.isSupportedOption(option);
		}

		public boolean isSameFile(FileObject a, FileObject b) {
			return defaultWrapper.isSameFile(a, b);
		}

		public Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles(Iterable<? extends File> files) {
			return defaultWrapper.getJavaFileObjectsFromFiles(files);
		}

		public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) {
			return defaultWrapper.getJavaFileObjects(files);
		}

		public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable<String> names) {
			return defaultWrapper.getJavaFileObjectsFromStrings(names);
		}

		public Iterable<? extends JavaFileObject> getJavaFileObjects(String... names) {
			return defaultWrapper.getJavaFileObjects(names);
		}

		public void setLocation(Location location, Iterable<? extends File> path) throws IOException {
			defaultWrapper.setLocation(location, path);
		}

		public Iterable<? extends File> getLocation(Location location) {
			return defaultWrapper.getLocation(location);
		}
	}
}
分享到:
评论

相关推荐

    jdk1.5 jdk1.6 反编译 工具

    标题中的“jdk1.5 jdk1.6 反编译 工具”指的是用于对Java字节码进行反编译的软件,这类工具能够将Java的.class文件转换回可读的.java源代码形式,这对于理解和学习已有的Java类库或者进行逆向工程非常有帮助。...

    jdk1.8class反编译

    在 JDK 1.8 版本中,开发者们有时需要查看已编译的`.class`文件的源代码,以便理解其内部工作原理或进行调试。这时,就需要用到反编译工具。反编译是从已编译的字节码文件(.class文件)还原出类似源代码的形式,...

    java jdk1.7源码包,用于centos7使用jdk1.7编译openjdk1.8的 1.7版本

    在开发和维护Java应用程序时,理解并熟悉JDK源码对于开发者来说至关重要,特别是当需要对源代码进行调试、优化或扩展时。 首先,让我们深入了解一下JDK 1.7的关键特性: 1. **Diamond操作符**:在JDK 7中引入了...

    自己重新编译的jdk源码jar包

    我们要明白在jdk中,sun对rt.jar中的类编译时,去除了调试信息,这样在eclipse中就不能看到局部变量的值。这样的话,如果在debug的时候查看局部变量, 就必须自己编译相应的源码使之拥有调试信息。要达到这个目的,一是...

    jdk-8u60源码

    `src`目录则包含了JDK的所有源代码,这是理解JDK内部机制的关键。Java 8引入了许多新特性,如Lambda表达式、Stream API、默认方法和接口的私有方法等。在`src`目录下,我们可以找到这些新特性的实现细节,例如`java....

    jdk源码调试重编译rt.jar包

    关于调试jdk源码显示源码变量值的rt.jar重编译包

    jdk反编译工具

    本文将深入探讨"jdk反编译工具"这一主题,帮助你了解如何借助此类工具解决无法查看源代码的问题。 首先,让我们了解什么是反编译。反编译是将已编译的计算机程序(通常为字节码或机器码)转换回接近原始源代码的...

    JavaCompiler --JDK6 API的简介(java动态编译)

    JavaCompiler 是 Java 中的一个编译器接口,提供了编译 Java 源代码的功能。在 Java SE6 中,JavaCompiler 接口是 javax.tools 包的一部分,提供了标准的方式来操作 Java 编译器。 使用 JavaCompiler 接口来编译 ...

    ubuntu 18.04编译JDK 12源码包

    解压该文件后,你将得到JDK 12的源代码。 在Ubuntu 18.04上编译JDK 12源码的步骤如下: 1. **安装依赖**:在编译源码之前,确保系统已经安装了必要的依赖库。打开终端并输入以下命令: ``` sudo apt-get update ...

    JDK源代码Java源码

    Java开发是每一个程序员在职业生涯中必须要面对的重要环节,而深入理解JDK源代码更是提升编程技艺的关键步骤。JDK(Java Development Kit)是Java平台的标准版,包含了Java运行时环境、Java工具和Java基础类库。Java...

    jdk1.8 + 反编译工具

    虽然反编译的代码可能不会完全与原始源代码相同,但对于理解逻辑和功能来说已经足够。这个工具对于排查问题、学习第三方库或者进行逆向工程来说,都是一个强大的辅助工具。 在实际开发中,了解JDK 1.8的新特性和...

    jdk反编译软件

    Java反编译是Java开发中一个重要的辅助工具,它允许开发者查看和理解已编译的Class文件中的字节码,因为Java源代码在编译后会被转换为这种不可读的二进制格式。标题提到的"jdk反编译软件"正是针对这个需求而设计的,...

    jdk6&openjdk;源代码

    此外,源代码中的异常处理、同步机制、网络编程模型等也是重要的学习内容。 通过阅读和分析OpenJDK源代码,开发者不仅可以提高自己的编程技能,还能为开源社区贡献自己的力量,修复bug、提出改进方案,甚至参与新的...

    jdk12源代码

    2. **jdk.internal.vm.compiler**: 通常称为JIT(Just-In-Time)编译器,这部分源代码涉及到HotSpot虚拟机的动态编译技术。JDK12可能引入了新的编译策略或优化,以提高代码执行效率。 3. **jdk.charsets**: 这个...

    java源代码,jdk里面的源代码

    Java JDK中的源代码是学习和理解Java编程语言及其运行机制的关键资源。这些源文件包含了Java开发工具集(Java Development Kit)的核心类库,涵盖了从基本的语法结构到高级特性的实现。下面我们将深入探讨这些源代码...

    最新java反编译工具jad 支持jdk1.6

    Java反编译是将已编译的Java字节码(.class文件)转换回源代码的过程,以便开发者能够查看和理解这些编译后的代码。JAD(Java Decompiler)是一款著名的开源Java反编译工具,它能帮助程序员分析、理解和重构已编译的...

    JDK7源代码

    虽然在JDK8之后,部分sun包已被移除或重命名,但在JDK7中,这部分源代码仍然是理解Java底层运行机制的关键。 sunw 目录: 这个目录在较旧的Sun Microsystems JDK中常见,主要用于提供特定于Solaris操作系统的类。在...

    jdk-1.6.0 源代码 二

    **Java JDK 1.6.0 源代码解析** Java Development Kit (JDK) 是Java编程语言的核心组件,它包含编译器、运行时环境、调试工具和其他实用工具。JDK 1.6.0 版本是历史上的一个里程碑,它在Java的发展历程中占有重要的...

    jdk1.5环境下编译的jar包在JDK1.4环境下运行

    在Java开发过程中,时常会遇到跨版本的问题,尤其是在旧版JDK环境中运行新版JDK编译的代码。这里我们讨论的焦点是“JDK1.5环境下编译的jar包在JDK1.4环境下运行”所遇到的问题,具体表现为“Unsupported major.minor...

    自己编译JDK

    标题“自己编译JDK”涉及的是一个技术过程,即如何从源代码层面构建Java Development Kit(JDK)。这个过程对于开发者来说具有重要的学习价值,因为它可以帮助深入理解JDK的工作原理,同时也为自定义功能或者优化JDK...

Global site tag (gtag.js) - Google Analytics