字节码是否可识别Java版本

时间:2018-01-09 01:54:14

标签: java jvm java-9 jigsaw

很抱歉,如果这是一个愚蠢的问题,我还没有找到答案。

我编写了一个用Java 9特性编写的程序并生成了一个.jar。

程序的本质是我需要它一次在两台机器上运行,一台运行java 8,另一台运行Java 9.我的程序无法运行,特别是jdk.incubator.httpclient模块无法发送从一台机器到另一台机器的HttpRequest。

不能将JDK8计算机更新为9。

我的问题是,一旦它变成字节码就重要了吗? Java 8 JVM无法理解Java 9生成的jar中是否存在字节码?

可能值得注意的是我必须使用java -jar --add-modules=jdk.incubator.httpclient运行jar来使用新的java 9孵化器模块httpclient

我理解一个聪明的解决方案是确保双方的防火墙允许这两个人交谈,但我也想知道上面的答案!

提前致谢。

这是stacktrace:

2018-01-09 01:15:57.410  INFO 4656 --- [nio-8080-exec-2] c.e.s.controller.MessageController       : [TO http://192.168.1.64:8080/send] Hello Bob it is Jim!
2018-01-09 01:18:08.551 ERROR 4656 --- [nio-8080-exec-2] c.e.s.service.MessagingService           : send: unable to send request 

java.net.ConnectException: Connection timed out
    at java.base/sun.nio.ch.Net.connect0(Native Method) ~[na:na]
    at java.base/sun.nio.ch.Net.connect(Net.java:454) ~[na:na]
    at java.base/sun.nio.ch.Net.connect(Net.java:446) ~[na:na]
    at java.base/sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:648) ~[na:na]
    at jdk.incubator.httpclient/jdk.incubator.http.PlainHttpConnection.connect(PlainHttpConnection.java:142) ~[jdk.incubator.httpclient:na]
    at jdk.incubator.httpclient/jdk.incubator.http.Http1Exchange.sendHeadersOnly(Http1Exchange.java:136) ~[jdk.incubator.httpclient:na]
    at jdk.incubator.httpclient/jdk.incubator.http.Exchange.responseImpl0(Exchange.java:298) ~[jdk.incubator.httpclient:na]
    at jdk.incubator.httpclient/jdk.incubator.http.Exchange.responseImpl(Exchange.java:245) ~[jdk.incubator.httpclient:na]
    at jdk.incubator.httpclient/jdk.incubator.http.Exchange.response(Exchange.java:121) ~[jdk.incubator.httpclient:na]
    at jdk.incubator.httpclient/jdk.incubator.http.MultiExchange.response(MultiExchange.java:154) ~[jdk.incubator.httpclient:na]
    at jdk.incubator.httpclient/jdk.incubator.http.HttpClientImpl.send(HttpClientImpl.java:234) ~[jdk.incubator.httpclient:na]
    at com.example.simplemessenger/com.example.simplemessenger.service.MessagingService.send(MessagingService.java:30) ~[classes/:na]
    at com.example.simplemessenger/com.example.simplemessenger.controller.MessageController.sendMessage(MessageController.java:71) [classes/:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:564) ~[na:na]
    at spring.web@4.3.13.RELEASE/org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) [spring-web-4.3.13.RELEASE.jar:na]
    at spring.web@4.3.13.RELEASE/org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) [spring-web-4.3.13.RELEASE.jar:na]
    at spring.webmvc@4.3.13.RELEASE/org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97) [spring-webmvc-4.3.13.RELEASE.jar:na]
    at spring.webmvc@4.3.13.RELEASE/org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) [spring-webmvc-4.3.13.RELEASE.jar:na]
    at spring.webmvc@4.3.13.RELEASE/org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) [spring-webmvc-4.3.13.RELEASE.jar:na]
    at spring.webmvc@4.3.13.RELEASE/org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) [spring-webmvc-4.3.13.RELEASE.jar:na]
    at spring.webmvc@4.3.13.RELEASE/org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967) [spring-webmvc-4.3.13.RELEASE.jar:na]
    at spring.webmvc@4.3.13.RELEASE/org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901) [spring-webmvc-4.3.13.RELEASE.jar:na]
    at spring.webmvc@4.3.13.RELEASE/org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) [spring-webmvc-4.3.13.RELEASE.jar:na]
    at spring.webmvc@4.3.13.RELEASE/org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) [spring-webmvc-4.3.13.RELEASE.jar:na]
    at tomcat.embed.core@8.5.23/javax.servlet.http.HttpServlet.service(HttpServlet.java:661) [tomcat-embed-core-8.5.23.jar:na]
    at spring.webmvc@4.3.13.RELEASE/org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) [spring-webmvc-4.3.13.RELEASE.jar:na]
    at tomcat.embed.core@8.5.23/javax.servlet.http.HttpServlet.service(HttpServlet.java:742) [tomcat-embed-core-8.5.23.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) [tomcat-embed-core-8.5.23.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.23.jar:na]
    at tomcat.embed.websocket@8.5.23/org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.5.23.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.23.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.23.jar:na]
    at spring.web@4.3.13.RELEASE/org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-4.3.13.RELEASE.jar:na]
    at spring.web@4.3.13.RELEASE/org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.13.RELEASE.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.23.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.23.jar:na]
    at spring.web@4.3.13.RELEASE/org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:108) [spring-web-4.3.13.RELEASE.jar:na]
    at spring.web@4.3.13.RELEASE/org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.13.RELEASE.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.23.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.23.jar:na]
    at spring.web@4.3.13.RELEASE/org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:81) [spring-web-4.3.13.RELEASE.jar:na]
    at spring.web@4.3.13.RELEASE/org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.13.RELEASE.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.23.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.23.jar:na]
    at spring.web@4.3.13.RELEASE/org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) [spring-web-4.3.13.RELEASE.jar:na]
    at spring.web@4.3.13.RELEASE/org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.13.RELEASE.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) [tomcat-embed-core-8.5.23.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) [tomcat-embed-core-8.5.23.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) [tomcat-embed-core-8.5.23.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-8.5.23.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:478) [tomcat-embed-core-8.5.23.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.23.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81) [tomcat-embed-core-8.5.23.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.23.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:342) [tomcat-embed-core-8.5.23.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:803) [tomcat-embed-core-8.5.23.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.23.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868) [tomcat-embed-core-8.5.23.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1459) [tomcat-embed-core-8.5.23.jar:na]
    at tomcat.embed.core@8.5.23/org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.23.jar:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) [na:na]
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) [na:na]
    at tomcat.embed.core@8.5.23/org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.23.jar:na]
    at java.base/java.lang.Thread.run(Thread.java:844) [na:na]

2018-01-09 01:18:08.552  INFO 4656 --- [nio-8080-exec-2] c.e.s.controller.MessageController       : failed to send

3 个答案:

答案 0 :(得分:3)

答案是肯定的。在Java 8上可以使用工具javap来查看它。

$ javap -v Hello.class | grep "version"
  minor version: 0
  major version: 52

在Java 9上,您可以看到

  minor version: 0
  major version: 53

但是,您可以使用编译器标志-target-source使Java 9编译器生成Java 8兼容代码。

$ javac -source 1.8 -target 1.8 Hello.java

但是,新的孵化器可能没有向后移植到Java 1.8;在这种情况下,我建议最好的办法是使用apache HttpComponents - 这应该适用于两者。

答案 1 :(得分:2)

这个问题有两个不同的组成部分。第一个问题是,正如其他人已经提到的,类文件包含一个版本标记,JVM将拒绝运行版本号太高的任何类文件,这意味着Java 8 JVM将拒绝包含Java 9版本代码的类文件(然而反之则非常好。)

更有趣的问题是,如果您手动将版本代码编辑为Java 8,您的代码是否可行。在这种情况下,它取决于。在字节码级别,Java 9中唯一值得注意的变化与模块和包有关。如果你不使用模块,你的代码应该仍然适用于Java 8,假设它所依赖的所有库也可以在Java 8中使用。

Java 9还为模块添加了几个属性,但这些对于运行时行为并不重要,除非使用反射,而JVM将忽略它无法识别的属性,因此不会停止代码从Java 8下运行。

所以tl;博士;假设您修复了版本字节,那么如果您不使用模块,那么您的代码应该在Java 8下运行。但是,如果您只需将-source-target标记传递给javac即可完成相同的操作,那就很麻烦了。

答案 2 :(得分:1)

  

我的问题是,一旦它变成字节码就重要了吗?在Java 9生成的jar中是否存在Java 8 JVM无法理解的字节码?

是的,运行Java 8的JVM将无法运行Java 9代码。您将需要使用Java 8进行编译。