Многомодульная библиотека с обфускацией кода - PullRequest
0 голосов
/ 09 июля 2020

У меня есть набор библиотек, распределенных как 3 отдельных архива. Есть ли способ обфускации каждой библиотеки независимо, но сохранить возможность вызова методов между модулями изнутри?

Например, если libA нужно вызвать myMethod из libB, но я не Я хочу, чтобы myMethod был доступен клиентам, интегрирующим мои библиотеки (но все библиотеки должны быть запутанными).

Прямо сейчас я вынужден сделать myMethod publi c и исключить его из обфускации, чтобы его можно было вызвать из libA. Есть ли лучшее решение этой проблемы, при котором myMethod не будет открываться клиентам, пока он будет запутан?

1 Ответ

0 голосов
/ 09 июля 2020

Лучше всего, чтобы библиотека предоставляла только интерфейс, а не объекты. Кроме того, интерфейс должен соблюдать принцип разделения интерфейса. Если вашему клиенту не нужно использовать этот метод, ваша библиотека тоже. Ваша libA - первый клиент вашей LibB. Ваши библиотеки должны соответствовать принципу единой ответственности. Я думаю, вам нужно переделать библиотеку и извлечь интерфейс для своих классов и предоставить только интерфейсы.

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

-keep public class mypackage.MyPublicClass {
    protected void myProtectedMethod();
}

Пример для рефакторинга:

//libA
class LibA {
    lateinit var libB:LibB
    fun serviceA(){
        libB.checkLicence()
    }
}
//libB
class LibB{
    fun serviceB(){}
    //this method is needed by libA, due to obfuscation visibility is public instead of internal
    //internal fun checkLicence(){}
    fun checkLicence(){}
}

отредактированный код может быть:

//new library distributed only internally not to customer 
// LibInternal
interface InternalLib {
    fun checkLicence()
}
internal class InternalLibImpl : InternalLib {
    override fun checkLicence() {
    }
}

object InternalLibFactory {
    fun create(): InternalLib = InternalLibImpl()
}

//LibB
interface LibB {
    fun serviceB()
}
class LibBImpl(private val internalLib: InternalLib) : LibB {
    override fun serviceB() {
        internalLib.checkLicence()
    }
}
object LibBFactory {
    fun create(): LibB = LibBImpl(InternalLibFactory.create())
}

//LibA
interface LibA {
    fun serviceA()
}
internal class LibAImpl(private val libB: LibB, private val internalLib: InternalLib) {
    fun serviceA() {
        internalLib.checkLicence()
        libB.serviceB()
    }
}
object LibAFactory {
    fun create(): LibB = LibBImpl(InternalLibFactory.create())
}
...