Страницы

Поиск по вопросам

четверг, 28 марта 2019 г.

Как научится разбиратся с ошибками во время разработки

В моём примере это отчёт об ошибках Tomcat Server.. Хотел узнать если есть какие либо программы или возможности упростить этот отчёт об ошибках в самом томкат сервере ? Может какнибудь настроить подругому ? Я как новичок замучался читать этот непонятный для меня отчёт.. вот пример:
java.lang.NoSuchMethodError: com.sun.jersey.core.spi.component.ProviderServices. (Lcom/sun/jersey/core/spi/factory/InjectableProviderFactory;Lcom/sun/jersey/core /spi/component/ProviderFactory;Ljava/util/Set;Ljava/util/Set;)V at com.sun.jersey.api.client.Client.(Client.java:172) at com.sun.jersey.api.client.Client.(Client.java:139) at com.sun.jersey.api.client.Client.create(Client.java:416) at appl.test.ApplTest.main(ApplTest.java:25) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Для меня очень трудно разобратся с данным ужасом как новичку и это очень сильно замедляет разработку.. Все возможные решения для этой проблемы будут приветствоватся.


Ответ

Что случилось?
Все на самом деле довольно несложно. Давайте просто читать стэктрейс по-порядку.
java.lang.NoSuchMethodError - эта ошибка бросается, когда во время выполнения программы JVM не может найти вызываемый метод. Очевидно на момент компиляции класса метод был доступен, иначе класс бы не скомпилировался. Такая ошибка, как правило появляется, если используются несовместимые версии библиотек.
Что это за метод? Его сигнатура следует далее:
com.sun.jersey.core.spi.component.ProviderServices.(Lcom/sun/jersey/core/spi/factory/InjectableProviderFactory;Lcom/sun/jersey/core /spi/component/ProviderFactory;Ljava/util/Set;Ljava/util/Set;)
в более читаемом виде метод - это конструктор:
ProviderServices(InjectableProviderFactory arg0, ProviderFactory arg1, Set arg2, Set arg3)
и, что немаловажно, стэктрейс сообщает нам, где именно вызов этого конструктора привел к ошибке:
at com.sun.jersey.api.client.Client.(Client.java:172)
Итого: у нас есть класс com.sun.jersey.api.client.Client, который на 172й строчке своего исходного кода вызывает конструктор ProviderServices из другой библиотеки, который ему не доступен.

Как это произошло?
Далее, попробуем найти это место. Вы легко можете перейти в IDE к нужному классу через поиск классов или Ctrl+клик на его имени, она подтянет исходники и вы окажетесь на этой злополучной 172й строке.
Но у меня такой возможности нет и я иду на http://grepcode.com/ - прекрасный поисковик по коду java-библиотек - и ищу класс com.sun.jersey.api.client.Client

Выясняется, что он входит в библиотеку jersey-client, и grepcode знает добрых три десятка версий этой библиотеки. Пробегаемся по версиям и смотрим на 172ю строчку. Это не так уж и долго. Выясняется, что ни в одной версии на 172й строке этот конструктор не вызывается. Может быть grepcode хранет в своем индексе не все-все версии jersey-client?
Отправляемся на http://mvnrepository.com/ - поисковик maven-артефактов и ищем jersey-client. Находим как org.glassfish.jersey.core:jersey-client так и com.sun.jersey:jersey-client. Нас интересует второй вариант, исходя из имени пакета com.sun.jersey. Действительно, выясняется, что версий вида 1.x.x было гораздо больше. Было бы досадно возиться со всем этим богаством. Но, к счастью, я нашел ваш недавний вопрос java.lang.NoSuchMethodError со списком ваших jar-ников.
Печально, что вы не удосужились приложить список библиотек к этому вопросу. Да и вообще, не совсем понятно, зачем плодить два почти одинаковых вопроса.
Но вернемся к нашему расследованию. Выберем из вашего списка то, что напрямую относится к Jersey:
jersey-client-1.0.3.jar jersey-client.jar jersey-common.jar jersey-container-servlet-core.jar jersey-container-servlet.jar jersey-core-1.8.jar jersey-entity-filtering-2.17.jar jersey-guava-2.22.2.jar jersey-media-jaxb.jar jersey-media-json-jackson-2.17.jar jersey-server.jar
Ага! Есть jersey-client-1.0.3.jar и неизвестный JAR jersey-client.jar (из чего я делаю вывод, что вы собирали библиотеки в кучу руками, а не каким-либо менеджером зависимостей). Что ж, попробуем посмотреть на jersey-client-1.0.3.jar. В нем есть класс com.sun.jersey.api.client.Client, и в его коде на 172й строчке наш конструктор:
ProviderServices providerServices = new ProviderServices( injectableFactory, this.componentProviderFactory, config.getClasses(), config.getSingletons());
Еще раз взглянем на список библиотек. Не может не смутить несоответствие версий jersey-core-1.8.jar и jersey-client-1.0.3.jar. Проверим на mvnrepository зависимости библиотеки jersey-client. Должна быть jersey-core версии 1.0.3!

На всякий случай посмотрим на grepcode исходники класса ProviderServices из jersey-core-1.8.jar - доступны только два конструктора:
ProviderServices(ProviderFactory componentProviderFactory, Set> providers, Set providerInstances)
и
ProviderServices(Class constraintToType, ProviderFactory componentProviderFactory, Set> providers, Set providerInstances)
, а нужного нам нет. Но он был единственным доступным конструктором в jersey-core-1.0.3.jar. Нестыковка действительно между версиями этих библиотек.
Поздравляю, это ваш первый JAR Hell

Что делать дальше?
Разобраться, какую версию jersey вы хотите использовать 1.0.3 или 1.8. Привести версии зависимостей в порядок, выкинуть лишние. Задуматься об использовании средств управления зависимостями (maven/ivy/gradle), чтобы никогда больше не заниматься раскладыванием jar-ников в /lib руками.

PS. Забудьте про "программы или возможности упростить этот отчёт об ошибках". Стэктрейс - это обычно все, что вам нужно при отладке исключений.

Комментариев нет:

Отправить комментарий