ClassNotFoundException на класс из jar, что я могу успешно загрузить другие классы из - PullRequest
2 голосов
/ 03 февраля 2012

Справочная информация: Я пытаюсь запустить встроенный сервер Tomcat в классе Java, запущенном через JRuby из сценария Ruby.Это означает, что все jar-файлы, которые я использую, должны быть загружены из скрипта ruby.

В скрипте ruby ​​у меня есть:

require 'java'
load 'servlet-api-2.5.jar'
...
com.mycompany.RunWebApplicationTomcat.main(nil)
//com.mycompany.RunWebApplicationJetty.main(nil)  //Commented out for Tomcat Test

И следующий класс Java:

   public class RunWebApplicationTomcat {

    public static void main(String[] args) throws Exception {

          try {
              Class.forName("javax.servlet.http.HttpServlet");
          } catch(ClassNotFoundException e) {
              System.err.println(e.getMessage());
          }

          DispatcherServlet dispatcherServlet =  new DispatcherServlet();
              ....
        }
   }

Задача: Когда я запускаю сценарий, я не получаю исключения для теста Class.forName, но получаю ClassNotFoundException для javax.servlet.http.HttpServlet при попытке инициализации DispatcherServlet.(DispatcherServlet - это пружинный сервлет, но я попробовал другие реализации сервлетов и столкнулся с тем же исключением)

Почему я на 99,9% уверен, что servlet-api.jar находится в classpath:Что действительно странно, так это то, что я успешно создал сервер Embedded Jetty, используя тот же шаблон.Этот сервер не требует класса HttpServlet.Однако он использует классы HttpServletRequest / Response, которые находятся в том же servlet-api.jar, и работает отлично.

Вопросы: 1. Есть ли у кого-нибудь представление о том, как один конкретный класс в jar-файле, загруженном в путь к классам, не может быть найден?
2. Существует ли какой-либо механизм безопасности java, который может предотвратить создание экземпляра класса?(Исполняемый файл JRuby - это нестандартный, собственный, черный ящик, поэтому я не уверен, что там может происходить)3. Могу ли я выполнить какие-либо другие тесты, которые могли бы пролить свет на проблему?

Stacktrace

Caused by: java.lang.NoClassDefFoundError: javax/servlet/http/HttpServlet
    ... 38 more
Caused by: java.lang.ClassNotFoundException: javax.servlet.http.HttpServlet
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)

Ответы [ 2 ]

2 голосов
/ 04 февраля 2012

A ClassNotFoundException может быть вызвано несколькими причинами, включая следующие:

  • Класса нет.

  • Класс существует, но другого класса / интерфейса / аннотации / перечисления, от которого он зависит, нет.

  • Ваш класс зависит от другого класса, который ранее не удался при инициализации класса.

Доказательства, кажется, противоречат всем этим. (Согласно javadoc, Class.forName(String) запускает инициализацию класса.) Однако трассировка стека предоставит больше доказательств.


Где здесь может быть что-то хитрое с загрузчиками классов; то есть класс DispatcherServlet был ранее загружен с загрузчиком классов, отличным от «текущего», который используется forName.

Вам также следует учитывать возможность того, что forName выдает другой Exception (или Error), который вы не проверяете в своем примере кода.

0 голосов
/ 19 ноября 2014

Tomcat предоставляет свою собственную версию servlet-api.jar. Различия в версии могут привести к отсутствию классов.

Из Tomcat 7.0 Документы :

Наконец, любой файл JAR, содержащий классы API сервлетов, будет явно проигнорирован загрузчиком классов. Не включайте такие JAR в ваше веб-приложение.

...