package com.scott.classloader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
public class MyClassLoader extends ClassLoader{
private String name;
private String path;
private final String fileType=".class";
public MyClassLoader(String name){
super();
this.name = name;
}
public MyClassLoader(String name, String path, ClassLoader parent){
super(parent);
this.name = name;
this.path = path;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
String filePath = name.replace(".", "\\");
filePath = path+filePath+fileType;
System.out.println("file path is : "+filePath);
byte[] b = loadClassData(filePath);
return defineClass(name, b, 0, b.length);
}
private byte[] loadClassData(String fileName) {
byte[] result = null;
ByteArrayOutputStream baos = null;
//FileInputStream fis = null;
InputStream inputStream = null;
try{
// //错误的实现方式导致了class文件和byte数组不一致,JVM检查不过
// baos = new ByteArrayOutputStream();
// inputStream = new FileInputStream(new File(fileName));
// //特别注意 !!!!!!!!!!!!!!!!!!!!!!!!!
// byte[] byteBuffer = new byte[1];//需要一个一个字节的读取,当是1024时,报错Exception in thread "main" java.lang.ClassFormatError: Extra bytes at the end of class file Parent
// while(-1 != inputStream.read(byteBuffer)){
// baos.write(byteBuffer);
// }
// result = baos.toByteArray();
baos = new ByteArrayOutputStream();
inputStream = new FileInputStream(new File(fileName));
int length = 0;
//特别注意 !!!!!!!!!!!!!!!!!!!!!!!!!
byte[] byteBuffer = new byte[1024];//
while(-1 != (length=inputStream.read(byteBuffer))){
baos.write(byteBuffer,0,length);
}
result = baos.toByteArray();
}catch(Exception e){
e.printStackTrace();
}finally{
if(null!=baos){
try {
baos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(null!=inputStream){
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
@Override
public String toString() {
return this.name;
}
public static void main(String[] args) throws Exception {
System.out.println("Hello MyClassLoader!");
//MyClassLoader loaderOne = new MyClassLoader("loader111", "e:/myapp/",ClassLoader.getSystemClassLoader());
MyClassLoader loaderOne = new MyClassLoader("loader111", "e:\\myapp\\",null);
System.out.println("start loade class");
Class<?> loadClass = loaderOne.loadClass("Parent");
System.out.println("the class is : "+loadClass);
Object newInstance = loadClass.newInstance();
}
}
//java.lang.ClassFormatError: Extra bytes at the end of class file
这个报错在网上查资料,说是JDK运行版本与编译版本不符合
我机器的情况是这样的:
C:\Users\Administrator>java -version
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b18)
Java HotSpot(TM) 64-Bit Server VM (build 25.25-b02, mixed mode)
C:\Users\Administrator>javac -version
javac 1.8.0
网上说报错的其中一种情况是编译版本低于运行版本
但是我在eclipse中通过系统类加载器加载类对象的方式没有任何问题,但是通过自定义类加载器加载就报错了,我也查看了eclipse的编译环境和运行环境JDK版本都是一致的。
所以我判定是读取class文件有问题,经过文件复制的查看,发现确实在读取文件的时候,需要一个字节一个字节的读取,这样才能保证*.class文件与原文件保持内容一致。才能符合jdk对java文件的文件结构检查,语意检查,操作码与操作数检查,二进制兼容性检查等。我想这里应该是二进制兼容性检查出问题了。
分享到:
相关推荐
在Java开发领域,`java.lang.ClassFormatError: Bad version information`是一个常见的错误,通常发生在尝试加载或执行不兼容的字节码时。这个错误表明Java虚拟机(JVM)遇到了一个它无法识别或者处理的类文件版本。...
java.lang.VerifyError 是一种验证错误,指的是在程序中验证器检测到某个类文件中存在内部不兼容或者安全问题时抛出的异常。 34. java.lang.VirtualMachineError 虚拟机错误 java.lang.VirtualMachineError 是一种...
在Java编程环境中,"ALERT: java/lang/ClassFormatError: Bad version information."是一个常见的错误提示,这通常意味着你的程序尝试加载一个与当前运行时环境不兼容的类文件。这个错误通常涉及到Java类版本的问题...
当类加载器检测到类之间的循环依赖时抛出。这通常是由于不正确的类加载配置或类设计问题。 10. **java.lang.ClassFormatError**: 表示从类文件读取的数据格式不符合Java类的规范。检查类文件是否损坏或由非Java...
14. **java.lang.ClassCircularityError** 和 **java.lang.ClassFormatError**: 这些属于更底层的错误,通常与类加载和类文件格式有关。它们可能是由于类的编译或打包问题导致的。 了解和正确处理这些异常对于编写...
当Java虚拟机或ClassLoader试图加载并找到特定类时,但在类路径中找不到该类的字节码文件(`.class`文件),则会抛出`java.lang.ClassNotFoundException`。此异常常见于以下情况: - **开发环境差异**:例如,在...
- **`java.lang.ClassFormatError`**:当JVM尝试读取不符合Java类格式的有效文件时抛出。 - **`java.lang.Error`**:表示严重问题,通常不应该被捕获,例如JVM内部错误或资源耗尽。 - **`java.lang....
12. **java.lang.AbstractMethodError**、**java.lang.AssertionError**、**java.lang.ClassCircularityError**、**java.lang.ClassFormatError**等: 这些是更底层的运行时错误,通常表明程序中存在严重的问题,如...
- **`java.lang.ClassFormatError`**:类文件格式错误时抛出。 - **`java.lang.OutOfMemoryError`**:内存不足时抛出。 - **`java.lang.StackOverflowError`**:栈溢出时抛出。 - **`java.lang....
- **`java.lang.ClassFormatError`**:类格式错误。当Java虚拟机试图从一个文件中读取Java类,而检测到该文件的内容不符合类的有效格式时抛出。 - **`java.lang.Error`**:错误基类,用于标识严重的程序运行问题。 -...
`ClassNotFoundException`是在运行时(或类加载时)无法找到指定类时抛出的异常。这通常发生在类路径设置不正确或者编译时能找到某个类而运行时却找不到的情况。例如,如果你在Java项目中引用了一个外部库中的类,但...
运行时异常(RuntimeException)包括那些由程序错误引起的异常,它们继承自`java.lang.RuntimeException`类。常见的运行时异常有: - `ArithmeticException`(算术异常):比如除以零的时候; - `...
5. **ClassLoader**:用于加载类的类加载器,是Java类加载机制的重要组成部分。 6. **Enum**:枚举类型的实现,实现了`Comparable<T>`和`Serializable`接口。 7. **Math**:数学工具类,提供了一系列数学运算的方法...
- **定义**:当Java虚拟机或者类装载器试图实例化某个类,而找不到该类的定义时抛出该错误。 - **示例**:类加载失败。 ##### 13. **域不存在错误**:`NoSuchFieldError` - **定义**:当应用试图访问或者修改某...
在Java中,异常是通过类的实例来表示的,这些类都继承自`java.lang.Throwable`类,它是所有异常和错误的根类。异常分为两种主要类型:Error和Exception。 1. **Error**: - `Error`类是所有错误的基类,通常表示...
在Java中,异常被组织成一个层次结构,根类是`java.lang.Throwable`,它有两个主要的子类:`Error`和`Exception`。`Error`通常表示系统级的错误,比如内存不足(`OutOfMemoryError`)或虚拟机错误(`...
- `loader`:分派给所定义类的类加载器。 - `buf`:包含`.class`文件数据的缓冲区。 - `bufLen`:缓冲区的长度。 **返回值**:返回Java类对象。如果遇到错误,则返回`NULL`。 **可能抛出的异常**: - `...