辅导:JAVA基础(JVM版本与class版本的问题)
来源:优易学  2011-11-3 12:39:31   【优易学:中国教育考试门户网】   资料下载   IT书店
  一个eclipse插件,运行时碰到问题。在解决过程中,发现自已对java运行时的JVM与class文件的兼容性还不太了解。解决完问题,才明白一些本来很浅显的问题。
  先说说出错的情况:
  插件:内置一个jetty web server,用来启动一个web程序框架。
  执行程序:指定了web的主路径,里面包含必须的web.xml和部署的web程序(包含了jsp)使用1.4.2的JDK,编译使用1.4。
  服务端程序:是同一个eclipse环境下的工程,也有编译好的jar包。
  如果依赖服务端jar包,启动时报错:
  java.lang.UnsupportedClassVersionError: com/sun/tools/javac/Main
  (Unsupported major.minor version 49.0)
  at java.lang.ClassLoader.defineClass0(Native Method)
  at java.lang.ClassLoader.defineClass(ClassLoader.java:539)
  如果依赖服务端工程,启动正常。
  解决问题过程:
  1:因为上面的出错情况,没有仔细看异常,认为是工程环境和jar包的class的版本不同。
  可能jar包的class的版本不能在当前JVM中使用。
  查了一下工程环境的class,是48.0(也就是1.4),又查jar包的class,也是48.0。why?
  对了,如果要查class的版本,很简单,二进制方式打开,看它的7,8字节,就是主版本号了。
  如果是00 30那就是48了。
  2:那怎么办?难道问题不出在依赖的服务端程序。嗯,还是看看异常吧。
  噢,报的是Main这个类是49.0的,不被JVM支持,那是,当前的JVM是48.0的。
  3:看看Main是哪里的,干啥的。仔细一查,Main是插件中的一个tools.jar包中的类,它的作用是用来编译jsp的。噢,有点明白了。插件中的tools.jar的版本是1.5的,不能在当前JVM中使用。
  但问题是:那和服务端工程有啥关系呢?难道。。。。
  4:由于依赖的工程,依赖了一大堆其它的东东,里面很有可能包含tools.jar。查一查,果
  然,它依赖了一个1.4版本的tools.jar . 唉,真相大白了。
  5:好了,问题很好解决了。办法A:将tools.jar换成1.4的。办法B:把JDK换成1.5的。
  6:注意一下,我的项目要求是,执行程序必须是1.4编译的,tools.jar是不能换的,一定要是1.5。
  依赖工程是1.4的。大家可能要问了,上面的办法B能行吗?答案是:完全可以。原因看下面的解释。
  对于java的熟手,处理此问题不难,但对于新手,可能会有几个误区,青年人网站提示有几个概念点。
  1:出了问题,一定要先看异常,如果不明白异常的含义,应该先问人,将异常代表的含义搞明白。
  2:48.0和49.0代表是class的版本,也就是1.4和1.5,这是常识。java文件的不同编译方式,导致不同的class版本。要查看class的版本很简单,但文件的5,6,7,8字节。class文件的完全格式,可以参看《深入java虚拟机》一书,有详细的描述。
  3:class与运行环境的关系,应该是向下兼容的。也就是说,一个1.4的JVM环境里,允许存在1.4或者低于1.4版本的class文件运行。这点一定要明白,否则遇到上面的问题一定会糊涂。因为在一个运行环境里,可能发现了1.4的class和1.3的class,觉得不可思议,往往会偏离问题的解决方向。
  4:在3的观点上,也就有两个结论:
  A:在1.4的环境里,不支持1.5的class,这就是异常要表达的意思。
  B:在1.5的环境里,可以支持1.5及以下版本的class,这就是我们上面的6的做法的解释。
  问题很简单,解决时耗了时间,主要是因为我对java原理还是不熟。记下来,加深一下记忆。并且,也督促一下自已,应该要将深入java虚拟机一书仔细看一遍。

责任编辑:小草

文章搜索:
 相关文章
热点资讯
资讯快报
热门课程培训