Использование MessagePack с Android

Кто-то пытался использовать MessagePack с приложением Android?
Является ли это возможным? Я пытался использовать банку из msgpack-java и получил следующее исключение:

Caused by: java.lang.ExceptionInInitializerError
  at org.msgpack.Packer.pack(Packer.java:532)
  at org.msgpack.MessagePack.pack(MessagePack.java:31)
  ... 15 more
  Caused by: java.lang.ExceptionInInitializerError
  at org.msgpack.template.TemplateRegistry.<clinit>(TemplateRegistry.java:38)
  ... 17 more
  Caused by: java.lang.VerifyError: org.msgpack.template.BeansFieldEntryReader
  at org.msgpack.template.builder.BeansTemplateBuilder.<init (BeansTemplateBuilder.java:42)
  at org.msgpack.template.builder.BuilderSelectorRegistry.initForJava(BuilderSelectorRegistry.java:73)
  at org.msgpack.template.builder.BuilderSelectorRegistry.<clinit>(BuilderSelectorRegistry.java:38)
  ... 18 more

Код, который я использую, очень прост

PrintWriter out = new PrintWriter(socket.getOutputStream());
Message msg = new Message();
msg.body = "asdasdasd";
msg.from = "qwe";
msg.to = "ttt";
byte[] bytes = MessagePack.pack(msg);
out.print(bytes);
out.flush();

я имею javassist.jar, msgpack-0.5.2.jar, slf4j-api-1.6.2.jar а также slf4j-jdk14-1.6.2.jar в моем lib каталог.

В моем серверном приложении этот код прекрасно работает с теми же библиотеками.

4 ответа

Решение

(Надеюсь) ЗАКЛЮЧИТЕЛЬНОЕ ОБНОВЛЕНИЕ

msgpack: 0.6.8 работает на Android без проблем

msgpack-rpc: 0.7.0 работает на Android с одной оговоркой.

В частности, вам нужно добавить следующее onCreate для API уровня 8 (Android 2.2.1) и, возможно, ниже:

java.lang.System.setProperty("java.net.preferIPv4Stack", "true");
java.lang.System.setProperty("java.net.preferIPv6Addresses", "false");

из-за этой ошибки.

Если вы хотите увидеть простой пример, вот пара проектов, созданных для этой цели:


Предыдущие версии

ОБНОВЛЕНИЕ: по состоянию на 0.6.7 msgpack должен быть совместим с Android (есть небольшая проблема исключения зависимостей). Проверьте текст ниже для msgpack-rpc (который также может быть адаптирован в будущем).

ПРИМЕЧАНИЕ. Если вы также используете msgpack-rpc, вам необходимо выполнить следующие шаги:

  1. Загрузите исходный файл msgpack-rpc с git: //github.com/msgpack/msgpack-rpc.git (в частности, в папку "java").
  2. Измените основную версию артефакта msgpack на ту, которую вы создали.
  3. В org.msgpack.rpc.loop.netty.NettyEventLoop измените NioClientSocketChannelFactory на OioClientSocketChannelFactory (getWorkerExecutor ()).
  4. Создайте MessagePack-RPC таким же образом, как и в случае основного JAR-файла MessagePack (см. Шаг 11 выше).

Замена NettyEventLoop вызвана этой проблемой: http://markmail.org/message/ypa3nrr64kzsyfsa.

Важно: я проверил только синхронную связь. Асинхронный может не работать.


И вот причина того, что msgpack не работает с Android до 0.6.7 :

Причина ошибки заключается в том, что MessagePack использует несколько классов java.beans, которые не включены в Android SDK. Вы, вероятно, используете аннотацию MessagePackBeans.

Это проблема, аналогичная описанной здесь, для которой общее решение изложено здесь. К сожалению, в нашем случае это требует перекомпоновки msgpack. Вот что я сделал (вы почти наверняка можете пропустить шаги 5 и 8, но я не пробовал так):

  1. Загрузите исходный код MessagePack с https://github.com/msgpack/msgpack-java.git.
  2. Импортируйте источник MessagePack как проект в вашей IDE.
  3. Загрузите исходный код Apache Harmony для соответствующих пакетов с http://svn.apache.org/repos/asf/harmony/enhanced/java/trunk/classlib/modules/beans/src/main/java.
  4. Скопируйте эти пакеты в папку src / main / java вашего проекта MessagePack:
    • java.beans
    • java.beans.beancontext
    • org.apache.harmony.beans
    • org.apache.harmony.beans.internal.nls
  5. В вашем проекте MessagePack удалите следующие классы:
    • PropertyChangeListener
    • IndexedPropertyChangeEvent
    • PropertyChangeEvent
    • PropertyChangeListenerProxy
    • PropertyChangeSupport
  6. Переименуйте пакеты java.beans во что-то другое, например, custom.beans.
  7. Измените все ссылки на java.beans на переименованный идентификатор, например, на custom.beans. Это особенно относится к BeansFieldEntryReader (этот класс является причиной исходной ошибки).
  8. Измените ссылки на custom.beans для пяти классов, которые вы удалили на шаге 5, обратно на java.beans.
  9. В классе org.apache.harmony.beans.internal.nls.Messages закомментируйте метод setLocale и удалите связанный с ним импорт.
  10. Удалите все классы, в которых все еще есть ошибки, кроме Encoder. В этом классе закомментируйте все ссылки на классы, которые вы удалили. Теперь у вас должен быть безошибочный проект.
  11. Создайте JAR-файл MessagePack:
    • Если вы используете Maven, измените версию в pom.xml на нечто уникальное, запустите сборку Maven с целью установки, а затем добавьте зависимость в свой проект Android с этой версией.
    • Если вы не используете Maven, вам нужно запустить цель jar для Ant с помощью включенного build.xml. Замените msgpack JAR в вашем проекте Android на этот.
  12. Если вы публикуете свое приложение, не забудьте включить соответствующее юридическое уведомление для Apache Harmony. Это лицензия Apache, как и MessagePack.

Это должно сделать это. Используя ваш пример кода и мой собственный класс данных, я смог успешно упаковать и распаковать данные.

Весь ритуал переименования связан с тем, что компилятор DEX жалуется на именование пакетов java.*.

Я предлагаю вам написать это в главном файле правил proguard-

-dontwarn org.msgpack.**
-keep class org.msgpack.** { *; }

Существует критическая ошибка в сообщении msgpack о том, что данные, упакованные в msgpack, будут повреждены на виртуальной машине Dalvik. http://jira.msgpack.org/browse/MSGPACK-51

@TheTerribleSwiftTomato и основная команда MessagePack прилагают все усилия, чтобы заставить MessagePack работать на Android, см. Связанную проблему GitHub. Исправление, упомянутое в ответе @ TheTerribleSwiftTomato, можно найти здесь.

Обновить

Мне удалось, по крайней мере, запустить его на Android, добавив все необходимое javassist Классы, которые в настоящее время необходимы для успешной сборки. Дополнительный 600KB увеличение в размерах, но, по крайней мере, это похоже на работу. В общем и целом, похоже, что он работает в некоторой степени на Android, в конечном итоге обратитесь к менее известным ресурсам о Message Pack, таким как его группа пользователей и его Wiki для получения дополнительной информации.

Напомним, что обязательно используйте библиотеку HTTP-запросов (например, Android Async HTTP LoopJ или HttpClient Apache), которая может обрабатывать двоичные данные.

И последнее, но не в последнюю очередь вы можете пинговать меня, если есть интерес к этому jar что делает MessagePack, по-видимому, работающим на Android - кредиты, конечно, идут @TheTerribleSwiftTomato, который предоставил исправление выше!

Другие вопросы по тегам