Налаштуємо відмовостійкий Redis кластер на Highload fwdays | 13 жовтня
×Закрыть

Питання по java

Доброго дня народ.

Вчора зіткнувся з тим, що програма працює в оточенні jre, відпрацьовують тести, а на емуляторі отримую

java.lang.NoSuchMethodError: org.json.JSONObject.keySet
Саму бібліотеку json.jar скачав, поклав у папку лібс, додав її в бібліотеки в idea.
Гугєл каже, що тут конфліктують імена класів бібліотеки та андроїдної реалізації орг.жсон.

Так от питання — чи можна пояснити машині, щоб вона брала то, шо їй дають, а не те, що вона знайде у себе в оточенні?
Бо, бачу, проблема може торкнутися будь-якої бібліотеки, якщо виробник вирішить запхнути її в свою реалізацію андроїду.

пс. і якщо є гідний мануал по мавену не буржуйською мовою — дайте тиц. бо людина, розбещена IDE та pip install, не стикалася з цими системами.

LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

дам дельный совет — смени свою джсон либу на гугловскую, если можешь

Артем, объяснить, почему совет дельный сможете?

да. гугловская либа для джсон умеет все, а учитывая, что она есть в android sdk, то это удобно

дякую, зверну увагу. Впринципі gson я спробував, працює нормально. проте в цьому конкретному випадку в json даних я отримую об’єкти з різною кількістю полів, частина з яких — масиви з даними різних типів, частина — строки/числа. Gson-у треба передати об’єткт, на який будуть відображатися дані. а об’єкт виходить надто загальним, щось на зразок Map<object, object="">, а далі ітеруватися по елементам і приводити типи.
Мені здалося що підхід org.json простіший.
Але для серіалізації об’єктів з більш чітко визначеною структурою буду, мабуть, використовувати gson.
Дякую за пораду)

плохот смотрел
вот не отхотя в гугл напишу код, которій десериализует именно в то, что тебе нужно:
JsonElement el = new JsonParser().parse("{'a':'b', 'c':'d'}"); if(el.isJsonObject()){ JsonObject elObj = el.getAsJsonObject(); String aVal = elObj.get("a").getAsString(); }
проверку можешь упустит, если уверен в том, что там у тебя именно объект а не масив или примитив
гугловская библиотека полноценна и умеет все, в том числе и работать с объектами с произвольной структурой.

да, плохо. я ж как — гсон, оффпейдж, Gson User Guide. а там примеры используют BagOfPrimitives obj2 = gson.fromJson(json, BagOfPrimitives.class);
вот сейас глянул детальней — да, дофига всего, надо глубжее посмотреть

а у меня строки типа

'{
    "randomName1": [String, int, float, String,.......],
    "randomName2": [String, int, float, String,.......],
    ....
    "randomNameN": [String, int, float, String,.......],
    "full_count": int, 
    "version": "v4",
    ....
}'
т.е. мне нужно итерироваться по полям/ключам, а внутри по массиву. Єто не сложно, но в том самом юзерГайде упор на fromJson, которому нужно дать класс, а класс будет только общим, а потом всё равно его вручную обрабатывать. Обломался я именно этот пример по мануалу делать.
в орг.жсон мне показалось проще
JSONObject  jsonObject = new JSONObject(jstr);
Iterator keys = jsonObject.keys();
while(keys.hasNext()){...}

Set<Entry<String, JsonElement>> com.google.gson.JsonObject.entrySet()

Returns a set of members of this object. The set is ordered, and the order is in which the elements were added.

дальше можешь у этого Set получить итератор (так как это коллекция) и работать точно так же как и в коде выше.

их родной гайд не очень, согласен,
просто знай, что эта либа умеет все, а как именно — уже подскажет поиск в гугле

Не уверена, но возможно, проблема в том, что в класслоудер попадает 2 (и более) библиотеки в разных версиях, и при обращении за методом вызывается метод у той версии библиотеки, где нет реализации этого метода. Такое может произойти, например, когда одна библиотека тянет за собой транзитивную зависимость, которая уже находится в dependencies под другой версией. Посмотреть дерево Ваших прямых и транзитивных зависимостей можно с помощью команды mvn dependency:tree из командной строки, либо, более удобный способ — UI менеджер зависимостей присутствует в Eclipse IDE (просто открываете pom.xml файл в Eclipse во вкладке dependency tree. Детальней здесь — books.sonatype.com/...ze-depend.html.

Я знаю 2 способа решения проблем с версиями библиотек в транзитивных зависимостях

  • Исключением конфликтных транзитивных зависимостей и определением их под нужной версией в качестве прямых
  • С помощью dependencyManagement

UPD: Мой ответ может подойти, если проблема относится к проекту, построенному на Apache Maven.

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

дякую. мавен вже вчу, до останніх днів ним не користувався — полагався цілком на ide.

Може питання здасться трошки дебилкуватим, але ви не намагалися явно задати dependency?
Відправив Вам лінк на документацію по maven, що в мене є. Все англійскою, але ж......

проитал как «питание по java» — завис

Спробуйте в налаштуваннях проекту змінити параметр «Scope» на «Provided» — подібна ситуація складалась з аналітикою Google(компілюється нормально, а працювати не буде через RuntimeException «NoClassDefFoundError»). Після правильного налаштування експорту бібіліотек має працювати «як годинник».

java.lang.NoSuchMethodError: org.json.JSONObject.keySet
Тут проблема, схоже, саме в різних версіях біліотеки, бо якщо переписати приклад з використанням лише JSONObject.keys(), то все працює.
Також бібліотека Gson підключається нормально і працює на емуляторі (а в інетах є інформація про те, що народ стикався з проблемою версій і для Gson на тих апаратах, де виробники додавали бібліотеку в свою реалізацію андроїду. і вирішували проблему шляхом перейменування бібліотеки)

Колись такі питання питали на тематичних форумах по кожній з мов програмування,
зараз же ж народ пише куди попало... І це сумно ((

P.S. Гугл в поміч ;)

модні явісти кажуть «та фігня вапрос. додай депендісі в свій білд.грейдл/мавен.пом і воно все само зробить». з іншого боку медалі — «ось вам послідовність скріншотів, як це зробити у екліпсі, зробіть точно так і буде вам щястя»
тобто я не проти розібратися в мавені — в принципі зараз читаю якраз — але я далеко не впевнений, що конфлікту імен можна запобігти без перейменування. Тому і запитав тут.
На проффоруми з нубськими питаннями йти стидно)

а про «куди попало» це ви даремно. всетаки девелоперз.оф.юкрейн, а не фансайт битви екстрасенсів

На проффоруми з нубськими питаннями йти стидно)
Всі з таких починали, і всі без винятку колись були «нубами», нема чого стидатись.
Хоча саме завдяки цьому, ти триста разів перебереш всі варіанти, а потім спитаєш ;)
а про «куди попало» це ви даремно. всетаки девелоперз.оф.юкрейн, а не фансайт битви екстрасенсів
просто тут зазвичай обговорюють більш загальні питання,
і не хотілось би щоб «девелоперз.оф.юкрейн» перетворювалось в сайт «поможіть.зробити.фічу».
Якщо такий сайт потрібен — то його, думаю, нескладно зробити як окремий сервіс ;)
Хоча саме завдяки цьому, ти триста разів перебереш всі варіанти, а потім спитаєш ;)
да. але тут питання чи можливо вирішити проблему в принципі, бо однозначної відповіді в інетах не знайшов.

будь-яку проблему можна вирішити в принципі, тільки різними методами.
На форумах якраз можна піднімати такі питання, і там швидше знаходиться правильна відповідь,
якщо проблема в принципі не вирішується — то ви хоча б знайдете там, коло людей які знають якийсь можливий workaround, для цього питання..

Stackowerflow, там подобных вопросов 100500

да. саме там всі рекомендують додати депенденсі в gradle.
в даному конкретному випадку мені буде швидше змінити бібліотеку на ту, що не конфліктує, або взагалі розпарсити лапшою говнокоду все)
Та й сама бібліотека в проект, схоже, потрапляє. Граблі починаються на девайсі, тому що там вже є ця бібліотека, але старішої версії.

Подписаться на комментарии