pcap4j - Конфигурация Android Proguard/R8

Я использую pcap4j на Android, и все хорошо работает на Debug Build. Но в сборке релиза при активации Proguard/R8 выдается следующее исключение:

java.lang.IllegalStateException: Unsupported target: class org.pcap4j.packet.IpV4Rfc1349Tos
        at org.pcap4j.packet.factory.PacketFactoryBinder.getPacketFactory(SourceFile:2)
        at org.pcap4j.packet.factory.PacketFactories.getFactory(SourceFile:2)
        at org.pcap4j.packet.IpV4Packet$IpV4Header.<init>(SourceFile:6)
        at org.pcap4j.packet.IpV4Packet.<init>(SourceFile:2)
        at org.pcap4j.packet.IpV4Packet.newPacket(SourceFile:2)
        at org.pcap4j.packet.factory.StaticEtherTypePacketFactory.newInstance(SourceFile:10)
        at org.pcap4j.packet.factory.StaticEtherTypePacketFactory.newInstance(SourceFile:1)
        at org.pcap4j.packet.IpSelector.newPacket(SourceFile:8)

В качестве обходного пути для этого это работает нормально, если я добавлю это правило:

-keep class org.pcap4j.packet.**

Но с вышеприведенным правилом все классы хранятся в усадке и не оптимизируются

Мой вопрос заключается в том, как написать более строгое правило для максимального сокращения pcap4j и сохранения функциональности без исключения броска.

Я пробовал тоже с правилами ниже, но все еще сбой:

-keepclassmembernames class org.pcap4j.packet.**
-keepclassmembers class org.pcap4j.packet.**
-keepnames class org.pcap4j.packet.**

Итак, еще один обходной путь - сохранить эти 2 класса в этом случае, и все будет работать нормально:

-keep class org.pcap4j.packet.IpV4Packet
-keep class org.pcap4j.packet.IpV4Rfc1349Tos

Но я прошу "общее" правило, потому что в этом случае приложение может использовать другие классы, подобные приведенным выше.

Спасибо

1 ответ

Решение

Предоставление определенных правил для данной библиотеки обычно требует некоторого понимания того, как библиотека работает, и, в частности, где библиотека использует отражение. В мире префектов поставщик библиотеки будет включать в себя необходимые правила, см. [Рекомендации по разработке модулей библиотеки]. ( https://developer.android.com/studio/projects/android-library).

Когда R8 (или Proguard) обрабатывает код, он будет отслеживать весь код, достижимый из классов / методов / полей, которые указаны для соблюдения указанных правил. Это хорошо работает для всего кода, кроме отражения. Когда используется отражение, обычно предполагается, что отраженные элементы будут присутствовать, и все еще будут иметь свои оригинальные имена. Поэтому для предметов, о которых идет речь, обычно требуется правило хранения.

Обратите внимание, что в простых случаях отражение обрабатывается, например:

  Class.forName("com.example.MyClass")

Здесь трассировка будет отслеживать класс com.example.MyClassи, если запутывание включено, класс также может быть переименован, и константная строка затем также переписывается.

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