Знает ли байт-код версию Java
Извините, если это глупый вопрос, мне не удалось найти прямой ответ.
Я скомпилировал программу, написанную с использованием функций Java 9, и создал.jar.
Суть программы заключается в том, что она должна работать на двух компьютерах одновременно, одна работает на Java 8, а другая на Java 9. Моя программа не работает, в частности, модуль jdk.incubator.httpclient не может отправить HttpRequest с одного машина к другому.
Обновление машины JDK8 до 9 не вариант.
Мои вопросы, как только все это становится байт-кодом, имеет ли это значение? Будет ли в jar-файле Java 9 байт-код, который Java 8 JVM не может понять?
Возможно, стоит отметить, что я должен запустить банку с java -jar --add-modules=jdk.incubator.httpclient
использовать новый модуль инкубатора Java 9 httpclient
Я понимаю, что разумным решением было бы убедиться, что межсетевой экран с обеих сторон позволяет этим двум разговаривать, однако я также хотел бы узнать ответ на вышесказанное!
Заранее спасибо.
Вот трассировка стека:
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 ответа
Ответ - да. Инструмент javap
можно использовать, чтобы увидеть это, на Java 8
$ 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 - это должно работать на обоих.
В этом вопросе есть два разных компонента. Первая проблема заключается в том, что, как уже упоминали другие, файлы классов содержат тег версии, и JVM откажутся запускать любые файлы классов с слишком большим номером версии, что означает, что JVM Java 8 будут отклонять файлы классов, содержащие код версии Java 9 (реверс однако вполне нормально).
Более интересный вопрос - будет ли работать ваш код, если вы вручную отредактировали код версии на Java 8. В этом случае это зависит. На уровне байт-кода единственные заметные изменения в Java 9 были связаны с модулями и пакетами. Если вы не используете модули, ваш код все еще должен работать на Java 8, при условии, что все библиотеки, на которые он опирается, также доступны в Java 8.
Java 9 также добавила пару атрибутов для модулей, но они не важны для поведения во время выполнения, за исключением случаев, когда используется отражение, и JVM будет игнорировать атрибуты, которые не распознает, поэтому это не остановит ваш код от запуска под Java 8.
Так что TL; Dr; в том, что ваш код должен работать под Java 8, если вы не используете модули, при условии, что вы исправили байт версии. Тем не менее, это большая проблема, когда вы можете просто передать -source
а также -target
флаги для javac
сделать то же самое.
Мои вопросы, как только все это становится байт-кодом, имеет ли это значение? Будет ли в jar-файле Java 9 байт-код, который Java 8 JVM не может понять?
Да, JVM, работающая на Java 8, не сможет выполнять код Java 9. Вам нужно будет скомпилировать его с Java 8.