tools.jar отсутствует, но только при первом вызове (Tomcat 8/Java 8/Axis)

Теперь, когда я обновил свое веб-приложение до Java 8, я столкнулся со странной проблемой загрузки классов с веб-службой оси, которая работает в Tomcat 8.

Самый первый вызов веб-службы после установки веб-приложения вызовет исключение RuntimeException и ошибку «Компилятор не найден в вашем пути к классам! (Вам может потребоваться добавить «tools.jar»)».

Все последующие вызовы этого веб-сервиса работают правильно (видимо, tools.jar все-таки есть?).

Поведение можно воспроизвести, удалив развернутую папку веб-приложения в каталоге развертывания. После следующего запуска tomcat первый вызов снова завершится ошибкой. Если взорванная папка уже существует, перезапуск tomcat не вызывает ошибку.

Ошибка не возникала, когда tomcat/веб-приложение все еще работали с Java 7.

Теперь эта ошибка Оси имеет давнюю, давнюю традицию. Раньше решением было скопировать tools.jar в каталог lib tomcats (он же сделал tools.jar доступным в пути к классам tomcats). По умолчанию его там нет, потому что ось, по-видимому, работает с JRE (даже если вы запускаете tomcat с JDK в JAVA_HOME).

К сожалению, это не помогло. Я попробовал несколько способов поместить tools.jar в путь к классам tomcats:

  • Я добавил его в путь к классам через setenv.bat
  • Я добавил его в одобренную папку lib
  • Больше идей?

Ничто не помогло, самый первый звонок все равно не удавался.

Затем я поиграл с JAVA_HOME и JRE_HOME. Tomcat начинает с JRE, когда это возможно, и использует JDK только в том случае, если вы используете некоторые функции, которым нужен JDK. Я пытался заставить tomcat использовать JDK вместо JRE, но ошибка сохраняется.

Итак, время вопросов:

  1. В чем разница в загрузке классов, когда tomcat взрывает webapp.war по сравнению со случаем, когда война уже была взорвана при более раннем запуске сервера?

  2. При запуске tomcat пишет в лог-файл следующее:

Версия сервера: Apache Tomcat/8.0.15
Дата сборки сервера: 2 ноября 2014 г., 19:25:20 UTC
Номер сервера: 8.0.15.0
Имя ОС: Windows Server 2008 R2
Версия ОС: 6.1
Архитектура: x86
JAVA_HOME: C:\Dev\Java\jdk1.8.0_25\jre
Версия JVM: 1.8.0_25-b18
Поставщик JVM: Oracle Corporation
CATALINA_BASE: C:\Dev\apache-tomcat-8.0.15
CATALINA_HOME: C:\Dev\apache-tomcat-8.0.15
Аргумент командной строки: -Djava.util.logging.config. file=c:\Dev\apache-tomcat-8.0.15\conf\logging.properties
Аргумент командной строки: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
Аргумент командной строки: -Djava.endorsed.dirs=c:\Dev\apache-tomcat-8.0.15\endorsed
Аргумент командной строки: -Dcatalina.base=c:\Dev\apache-tomcat-8.0.15
Командная строка аргумент: -Dcatalina.home=c:\Dev\apache-tomcat-8.0.15
Аргумент командной строки: -Djava.io.tmpdir=c:\Dev\apache-tomcat-8.0.15\temp

так что, по-видимому, он каким-то образом получил ссылку на JRE (хотя я указал только JDK, см. выше). Как я могу это изменить?

  1. Нет разницы.

Edit2: виновником является компиляция файлов .jws, которую ось выполняет при первом вызове веб-службы. Существование этих скомпилированных файлов является причиной того, что ошибка возникает только при первом вызове.

Конечно, это совсем не объясняет, почему первый вызов завершается с ошибкой "отсутствует компилятор", хотя необходимые скомпилированные файлы созданы и доступны для последующих вызовов...

Изменить: трассировка стека ошибки оси в соответствии с запросом. Ничего особенного по сравнению со всеми другими темами, посвященными отсутствующему файлу tools.jar:

Я добавил его в папку libs


person John    schedule 15.01.2015    source источник


Ответы (3)


  1. При запуске tomcat пишет в лог-файл следующее:

Возможно, некоторые файлы создаются в каталоге work для вашего веб-приложения при первом запуске.

JAVA_HOME: C:\Dev\Java\jdk1.8.0_25\jre

  1. Больше идей?

Это сообщение является значением System.getProperty("java.home"), зарегистрированным VersionLoggerListener.

Вот как работает программа запуска Java (java.exe). Это не имеет ничего общего с самим Tomcat.

Простая Java-программа:

Запуск его с помощью JDK печатает путь к JRE JDK, а не к JDK. В загрузочном пути к классам перечислены только библиотеки JRE (там нет tools.jar).

public class Test {
  public static void main(String[] a){
    System.out.println("java.home: "  + System.getProperty("java.home"));
    System.out.println("java.class.path: "  + System.getProperty("java.class.path"));
    System.out.println("sun.boot.class.path: "  + System.getProperty("sun.boot.class.path"));
  }
}

Обратите внимание, что системные свойства также можно проверить через jconsole, jvisualvm.

Явно добавьте tools.jar в CLASSPATH.

  1. Если вы запускаете Tomcat из файла *.bat, переменную CLASSPATH можно установить в setenv.bat.

Я ожидаю, что это сработает. Возможно, помимо tools.jar нужны какие-то другие jar-файлы JDK.

  • Если вы запускаете его как службу, используйте приложение настройки службы (tomcat8w.exe) для настройки пути к классам.
  • Если вы запускаете его из среды IDE, настройте параметры Java в среде IDE.
  • Я добавил его в папку libs
  • Я добавил его в путь к классам через setenv.

Вышеупомянутые два пункта работают, только если вы используете стандартные файлы *.bat для запуска Tomcat. Если вы запускаете его как службу или из IDE, настройки службы/IDE имеют значение. Файл setenv.bat ими не используется.

  • Я добавил его в одобренную папку lib
  • Фактическое сообщение в трассировке стека, которое я получаю, - это сообщение исходного плаката, но ему предшествует это.

Это также зависит от того, как Axis обнаруживает эту проблему. Я надеюсь, что он пытается загрузить какой-то класс (а не пытается найти конкретный файл jar). Подробнее в исходном сообщении? (Какой компонент регистрирует это? Трассировка стека? Исходный код?)

В чем разница в загрузке классов

person Konstantin Kolinko    schedule 18.01.2015
comment
Спасибо за Ваш ответ. Что касается пути к классам, я уже пробовал все, что вы упомянули, не сработало. Ваша идея о том, что файлы были созданы при первом запуске, верна. Axis скомпилировала файл webservice.jws в класс java для запуска (и сделала это, несмотря на то, что была выдана ошибка отсутствующего компилятора). Наверно буду дальше искать в этом направлении - ось ведет себя странно... - person John; 19.01.2015
comment
У меня была общая проблема с файлом JAR, который я добавил в путь к классам через setenv.bat, который не загружался для меня, когда я переместил свое приложение на JDK1.8 + Tomcat 8. На JDK1.7 + Tomcat 7 это работало нормально для меня даже когда я запускал Tomcat как службу Windows. Вместо этого добавление jar в запись реестра Classpath решило проблему с более поздним составом. Ваши комментарии выше побудили меня попробовать это, так что спасибо! - person John; 19.01.2015
comment
java.lang.RuntimeException: в вашем пути к классам не найден компилятор! (может потребоваться добавить «tools.jar»)
в org.apache.axis.components.compiler.Javac.compile(Javac.java:156)
в org.apache.axis.handlers.JWSHandler. setupService(JWSHandler.java:199)
в org.apache.axis.handlers.JWSHandler.invoke(JWSHandler.java:72)
в org.apache.axis.strategies.InvocationStrategy.visit(InvocationStrategy.java: 32)
на org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
на org.apache.axis.SimpleChain.invoke(SimpleChain.java:83)
на org.apache. axis.server.AxisServer.invoke(AxisServer.java:249) в org.apache.axis.transport.http.QSMethodHandler.invokeEndpointFromGet(QSMethodHandler.java:129)
в org.apache.axis.transport.http.QSMethodHandler .invoke(QSMethodHandler.java:94)
в sun.reflect.NativeMethodAccessorImpl.invoke0(собственный метод)
в sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
в sun.reflect. DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcc essorImpl.java:43)
на java.lang.reflect.Method.invoke(Method.java:483)
на org.apache.axis.transport.http.AxisServlet.processQuery(AxisServlet.java:1226)
на org.apache.axis.transport.http.AxisServlet.doGet(AxisServlet.java:249)
на javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
на org. apache.axis.transport.http.AxisServletBase.service(AxisServletBase.java:327)
в javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
в org.apache.catalina.core. ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
в org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
в org.apache.tomcat.websocket.server.WsFilter.doFilter( WsFilter.java:52)
на org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
на org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
в org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
на org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
на org.apache.catalina. AuthenticatorBase.invoke(AuthenticatorBase.java:501)
на org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
на org.apache.catalina.valves.ErrorReportValve.invoke( ErrorReportValve.java:79)
на org.apache.catalina.valves. AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
на org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
на org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter. java:537)
на org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1085)
на org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658)
> в org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:277)
в org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2407)
в org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2396)
в java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
в java. util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
в org.apache.tomcat.util.threads.TaskThread$WrappingRun nable.run(TaskThread.java:61)
на java.lang.Thread.run(Thread.java:745) - person John Rix; 22.04.2015

Похоже, что компилятор возвращает значение, отличное от ожидаемого, но компиляция все еще выполняется, и возникает исключение. Это с http://www.docjar.org/html/api/org/apache/axis/components/compiler/Javac.java.html

Я изменил код в axis-1_4\src\org\apache\axis\components\compiler\Javac.java на приведенный ниже, поскольку исходный код ожидает целое число для компиляторов до JDK 8. JDK 8 возвращает перечисление. Я сделал это только на своей локальной копии, пересобрал и работает нормально.

136             if (modern) {
137                 int compilationResult = 
138                     ((Integer)compile.invoke(compiler, new Object[] 
139                         {
140                             toStringArray(fillArguments
141                                           (new ArrayList()))})).intValue();
142 
143                 result = (compilationResult == 0);        
144                 log.debug("Compilation Returned: " 
145                           + Integer.toString(compilationResult));
146             }
147             else {
148                 Boolean ok = 
149                     (Boolean)compile.invoke(compiler, new Object[] 
150                         {toStringArray(fillArguments(new ArrayList()))});
151         
152                 result = ok.booleanValue();
153             }
154         } catch (Exception cnfe){
155             log.error(Messages.getMessage("noCompiler00"), cnfe);
156             throw new RuntimeException(Messages.getMessage("noCompiler00"));


5-Apr-2015 20:16:42 ERROR 160663 [http-nio-10470-exec-10] org.apache.axis.components.compiler.Javac.compile(Javac.java:155) - No compiler found in your classpath!  (you may need to add 'tools.jar')
java.lang.ClassCastException: com.sun.tools.javac.main.Main$Result cannot be cast to java.lang.Integer
        at org.apache.axis.components.compiler.Javac.compile(Javac.java:137)
        at org.apache.axis.handlers.JWSHandler.setupService(JWSHandler.java:199)
        at org.apache.axis.handlers.JWSHandler.generateWSDL(JWSHandler.java:294)
        at org.apache.axis.strategies.WSDLGenStrategy.visit(WSDLGenStrategy.java:33)
        at org.apache.axis.SimpleChain.doVisiting(SimpleChain.java:118)
        at org.apache.axis.SimpleChain.generateWSDL(SimpleChain.java:104)
        at org.apache.axis.server.AxisServer.generateWSDL(AxisServer.java:454)
        at org.apache.axis.transport.http.QSWSDLHandler.invoke(QSWSDLHandler.java:68)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:497)
        at org.apache.axis.transport.http.AxisServlet.processQuery(AxisServlet.java:1226)
        at org.apache.axis.transport.http.AxisServlet.doGet(AxisServlet.java:249)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
        at org.apache.axis.transport.http.AxisServletBase.service(AxisServletBase.java:327)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:516)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1086)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:659)
        at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1558)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1515)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:745)

У меня была та же проблема, и после нескольких часов попыток решить ее и перенастроить мой путь к классам сотни раз... кажется, я нашел решение, по крайней мере, то, которое подходит для моей ситуации.

Обновлять

// Call the compile() method

 Method compile = c.getMethod("compile",

                                     new Class [] { String[].class });

 if (modern) {

   log.info("Using modified axis for jdk 8 compiler");  
   Object compilationResult =  (compile.invoke(compiler, new Object[] 

                    {
                        toStringArray(fillArguments
                                      (new ArrayList()))}));

   result = ("OK".equalsIgnoreCase(compilationResult.toString()));        
  log.debug("Compilation Returned: "+ compilationResult);
        }
person Vijay Hirani    schedule 15.04.2015

Упомянутая вами ошибка исчезнет, ​​если вы измените версию JDK с 1.8 на 1.7!!

› Явно добавьте tools.jar в CLASSPATH.

person daniegarcia254    schedule 10.04.2015