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

#java #android #kotlin #android-proguard #android-r8

#java #Android #kotlin #android-proguard #android-r8

Вопрос:

я использую pcap4j на Android, и все хорошо работает при отладочной сборке. Но при сборке релиза при активации 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.**
  

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

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

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

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

Ответ №1:

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

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

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

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

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