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
и, если запутывание включено, класс также может быть переименован, и константная строка затем также переписывается.