今天学习ClassLoader的时候,参考视频自己写了个测试代码,报的这个错。
我一直以为是调用defineClass传入的第一个name参数的值有问题,或者是jar包中的文件有package但是没有将文件夹一起打包进入jar的问题。
然后重新看了下视频,再验证了猜想,没发现问题的根本原因。结果还是直接搜报错百度到了,读取class文件的时候多读写了字节数。
原代码:
@Override protected Class<?> findClass(String name) throws ClassNotFoundException { try { String ur = "jar:file:\D:/test/one/two.jar!/quartz/loader/" + name + ".class"; System.out.println(ur); URL url = new URL(ur); URLConnection urlConnection = url.openConnection(); InputStream inputStream = urlConnection.getInputStream(); ByteArrayBuffer byteArrayBuffer = new ByteArrayBuffer(); byte[] bytes = new byte[1024]; while (inputStream.read(bytes) != -1) { byteArrayBuffer.write(bytes); } return defineClass("quartz.loader.MyCalcSalary", byteArrayBuffer.toByteArray(), 0, byteArrayBuffer.toByteArray().length); } catch (Exception e) { e.printStackTrace(); } return null; }
修改后:
@Override protected Class<?> findClass(String name) throws ClassNotFoundException { try { String ur = "jar:file:\D:/test/one/two.jar!/quartz/loader/" + name + ".class"; System.out.println(ur); URL url = new URL(ur); URLConnection urlConnection = url.openConnection(); InputStream inputStream = urlConnection.getInputStream(); ByteArrayBuffer byteArrayBuffer = new ByteArrayBuffer(); byte[] bytes = new byte[1024]; int len; while ((len = inputStream.read(bytes)) != -1) { byteArrayBuffer.write(bytes, 0, len); } return defineClass(null, byteArrayBuffer.toByteArray(), 0, byteArrayBuffer.toByteArray().length); } catch (Exception e) { e.printStackTrace(); } return null; }
问题是:byteArrayBuffer.write的时候出现问题了,和defineClass的第一个参数没关系,因为jdk注释中有说明:如果你不知道这个name的值,那么你可以用null代替,说明这个值实际上无关紧要。