JetBrains / Exposed

Kotlin SQL Framework
http://jetbrains.github.io/Exposed/
Apache License 2.0
8.37k stars 694 forks source link

Any way to make Exposed work with Proguard? #449

Closed peterwilli closed 5 years ago

peterwilli commented 5 years ago

Hi there,

I tried optimizing/shrinking my application that works with Exposed with Proguard but I can't seem to get it to work. I added this to my config:

-keep class org.jetbrains.exposed.** { *; }
-keep class * extends org.jetbrains.exposed.dao.IntIdTable { *; }

But no luck. Adding:

-dontoptimize
-dontobfuscate
-dontshrink

Works, but that's not very helpful to begin with :) Anyone who knows what filters might work? Thanks!

Tapac commented 5 years ago

@peterwilli, could you provide a simple project with proguard setup to check what doesn't work?

peterwilli commented 5 years ago

@Tapac I don't know what happened here, but I got it working at some point... I'm sorry if I let this open for too long. I guess it was unrelated to Exposed.

Feel free to reopen if someone else still has this problem, I'm willing to help in that case.

Aditya94A commented 4 years ago

Hey @peterwilli how did you get it work? Please share your proguard rules

Here's the error that I get at the SchemaUtils.create() step:

Caused by: java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:567)
        at kotlin.reflect.jvm.internal.calls.CallerImpl$Method.callMethod(CallerImpl.kt:97)
        at kotlin.reflect.jvm.internal.calls.CallerImpl$Method$Instance.call(CallerImpl.kt:113)
        at kotlin.reflect.jvm.internal.KCallableImpl.call(KCallableImpl.kt:106)
        at kotlin.reflect.jvm.internal.KProperty1Impl.get(KProperty1Impl.kt:35)
        at org.jetbrains.exposed.sql.Table.clone(Table.kt:353)
        at org.jetbrains.exposed.sql.Table.cloneWithAutoInc(Table.kt:518)
        at org.jetbrains.exposed.sql.Table.autoIncrement(Table.kt:532)
        at org.jetbrains.exposed.sql.Table.autoIncrement$default(Table.kt:532)
        at org.jetbrains.exposed.dao.id.IntIdTable.<init>(IdTable.kt:42)
        at org.jetbrains.exposed.dao.id.IntIdTable.<init>(IdTable.kt:41)
        at corelib.db.BaseTable.<init>(BaseTable.kt:7)

And my BaseTable (parent table class for all my tables) is:

abstract class BaseTable : IntIdTable() {
    val createdAt = datetime("createdAt")
        .clientDefault { LocalDateTime.now() }
}

So something is tripping up because proguard removed something that is required in the instantiation of IntIdTable() or datetime field. (My driver is MySQL)

The stacktrace also trails off with the following:

Caused by: java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    com/mysql/cj/protocol/ExportControlled.encryptWithRSAPublicKey([BLjava/security/interfaces/RSAPublicKey;Ljava/lang/String;)[B @21: invokevirtual
  Reason:
    Type 'java/lang/Object' (current frame, stack[1]) is not assignable to 'java/security/GeneralSecurityException'
  Current Frame:
    bci: @21
    flags: { }
    locals: { top, top, top, 'java/lang/Object' }
    stack: { 'java/lang/Class', 'java/lang/Object' }
  Bytecode:
    0000000: 2cb8 00f4 4e2d 042b b600 f52d 2ab6 00f3
    0000010: b04e 123e 2db6 00de 2db8 00a3 c000 3ebf
    0000020:                                        
  Exception Handler Table:
    bci [0, 16] => handler: 17
    bci [0, 16] => handler: 17
    bci [0, 16] => handler: 17
    bci [0, 16] => handler: 17
    bci [0, 16] => handler: 17
  Stackmap Table:
    full_frame(@17,{},{Object[#81]})

        at com.mysql.cj.protocol.a.NativeProtocol.negotiateSSLConnection(NativeProtocol.java:311)
        at com.mysql.cj.protocol.a.NativeAuthenticationProvider.negotiateSSLConnection(NativeAuthenticationProvider.java:777)
        at com.mysql.cj.protocol.a.NativeAuthenticationProvider.proceedHandshakeWithPluggableAuthentication(NativeAuthenticationProvider.java:486)
        at com.mysql.cj.protocol.a.NativeAuthenticationProvider.connect(NativeAuthenticationProvider.java:202)
        at com.mysql.cj.protocol.a.NativeProtocol.connect(NativeProtocol.java:1340)
        at com.mysql.cj.NativeSession.connect(NativeSession.java:157)
        at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:956)
        at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:826)
        at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:456)
        at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:246)
        at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:197)
        at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:677)
        at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:228)
        at org.jetbrains.exposed.sql.Database$Companion$connect$7.invoke(Database.kt:105)
        at org.jetbrains.exposed.sql.Database$Companion$connect$7.invoke(Database.kt:60)
        at org.jetbrains.exposed.sql.Database$Companion$doConnect$3.invoke(Database.kt:84)
        at org.jetbrains.exposed.sql.Database$Companion$doConnect$3.invoke(Database.kt:60)
        at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManager$ThreadLocalTransaction$connectionLazy$1.invoke(ThreadLocalTransactionManager.kt:40)
        at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManager$ThreadLocalTransaction$connectionLazy$1.invoke(ThreadLocalTransactionManager.kt:32)
        at kotlin.UnsafeLazyImpl.getValue(Lazy.kt:81)
        at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManager$ThreadLocalTransaction.getConnection(ThreadLocalTransactionManager.kt:46)
        at org.jetbrains.exposed.sql.Transaction.getConnection(Transaction.kt)
        at org.jetbrains.exposed.sql.Database.metadata$exposed_core(Database.kt:31)
        at org.jetbrains.exposed.sql.Database$url$2.invoke(Database.kt:34)
        at org.jetbrains.exposed.sql.Database$url$2.invoke(Database.kt:17)
        at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
        at org.jetbrains.exposed.sql.Database.getUrl(Database.kt)
        at org.jetbrains.exposed.sql.Database$dialect$2.invoke(Database.kt:37)
        at org.jetbrains.exposed.sql.Database$dialect$2.invoke(Database.kt:17)
        at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
        at org.jetbrains.exposed.sql.Database.getDialect(Database.kt)
        at org.jetbrains.exposed.sql.vendors.DefaultKt.getCurrentDialect(Default.kt:357)
        at org.jetbrains.exposed.sql.vendors.DefaultKt.getCurrentDialectIfAvailable(Default.kt:361)
        at org.jetbrains.exposed.sql.Column.getOnDelete$exposed_core(Column.kt:18)
HenryLauu commented 3 years ago

Hey @peterwilli how did you get it work? Please share your proguard rules

Here's the error that I get at the SchemaUtils.create() step:

Caused by: java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:567)
        at kotlin.reflect.jvm.internal.calls.CallerImpl$Method.callMethod(CallerImpl.kt:97)
        at kotlin.reflect.jvm.internal.calls.CallerImpl$Method$Instance.call(CallerImpl.kt:113)
        at kotlin.reflect.jvm.internal.KCallableImpl.call(KCallableImpl.kt:106)
        at kotlin.reflect.jvm.internal.KProperty1Impl.get(KProperty1Impl.kt:35)
        at org.jetbrains.exposed.sql.Table.clone(Table.kt:353)
        at org.jetbrains.exposed.sql.Table.cloneWithAutoInc(Table.kt:518)
        at org.jetbrains.exposed.sql.Table.autoIncrement(Table.kt:532)
        at org.jetbrains.exposed.sql.Table.autoIncrement$default(Table.kt:532)
        at org.jetbrains.exposed.dao.id.IntIdTable.<init>(IdTable.kt:42)
        at org.jetbrains.exposed.dao.id.IntIdTable.<init>(IdTable.kt:41)
        at corelib.db.BaseTable.<init>(BaseTable.kt:7)

And my BaseTable (parent table class for all my tables) is:

abstract class BaseTable : IntIdTable() {
    val createdAt = datetime("createdAt")
        .clientDefault { LocalDateTime.now() }
}

So something is tripping up because proguard removed something that is required in the instantiation of IntIdTable() or datetime field. (My driver is MySQL)

The stacktrace also trails off with the following:

Caused by: java.lang.VerifyError: Bad type on operand stack
Exception Details:
  Location:
    com/mysql/cj/protocol/ExportControlled.encryptWithRSAPublicKey([BLjava/security/interfaces/RSAPublicKey;Ljava/lang/String;)[B @21: invokevirtual
  Reason:
    Type 'java/lang/Object' (current frame, stack[1]) is not assignable to 'java/security/GeneralSecurityException'
  Current Frame:
    bci: @21
    flags: { }
    locals: { top, top, top, 'java/lang/Object' }
    stack: { 'java/lang/Class', 'java/lang/Object' }
  Bytecode:
    0000000: 2cb8 00f4 4e2d 042b b600 f52d 2ab6 00f3
    0000010: b04e 123e 2db6 00de 2db8 00a3 c000 3ebf
    0000020:                                        
  Exception Handler Table:
    bci [0, 16] => handler: 17
    bci [0, 16] => handler: 17
    bci [0, 16] => handler: 17
    bci [0, 16] => handler: 17
    bci [0, 16] => handler: 17
  Stackmap Table:
    full_frame(@17,{},{Object[#81]})

        at com.mysql.cj.protocol.a.NativeProtocol.negotiateSSLConnection(NativeProtocol.java:311)
        at com.mysql.cj.protocol.a.NativeAuthenticationProvider.negotiateSSLConnection(NativeAuthenticationProvider.java:777)
        at com.mysql.cj.protocol.a.NativeAuthenticationProvider.proceedHandshakeWithPluggableAuthentication(NativeAuthenticationProvider.java:486)
        at com.mysql.cj.protocol.a.NativeAuthenticationProvider.connect(NativeAuthenticationProvider.java:202)
        at com.mysql.cj.protocol.a.NativeProtocol.connect(NativeProtocol.java:1340)
        at com.mysql.cj.NativeSession.connect(NativeSession.java:157)
        at com.mysql.cj.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:956)
        at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:826)
        at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:456)
        at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:246)
        at com.mysql.cj.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:197)
        at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:677)
        at java.sql/java.sql.DriverManager.getConnection(DriverManager.java:228)
        at org.jetbrains.exposed.sql.Database$Companion$connect$7.invoke(Database.kt:105)
        at org.jetbrains.exposed.sql.Database$Companion$connect$7.invoke(Database.kt:60)
        at org.jetbrains.exposed.sql.Database$Companion$doConnect$3.invoke(Database.kt:84)
        at org.jetbrains.exposed.sql.Database$Companion$doConnect$3.invoke(Database.kt:60)
        at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManager$ThreadLocalTransaction$connectionLazy$1.invoke(ThreadLocalTransactionManager.kt:40)
        at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManager$ThreadLocalTransaction$connectionLazy$1.invoke(ThreadLocalTransactionManager.kt:32)
        at kotlin.UnsafeLazyImpl.getValue(Lazy.kt:81)
        at org.jetbrains.exposed.sql.transactions.ThreadLocalTransactionManager$ThreadLocalTransaction.getConnection(ThreadLocalTransactionManager.kt:46)
        at org.jetbrains.exposed.sql.Transaction.getConnection(Transaction.kt)
        at org.jetbrains.exposed.sql.Database.metadata$exposed_core(Database.kt:31)
        at org.jetbrains.exposed.sql.Database$url$2.invoke(Database.kt:34)
        at org.jetbrains.exposed.sql.Database$url$2.invoke(Database.kt:17)
        at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
        at org.jetbrains.exposed.sql.Database.getUrl(Database.kt)
        at org.jetbrains.exposed.sql.Database$dialect$2.invoke(Database.kt:37)
        at org.jetbrains.exposed.sql.Database$dialect$2.invoke(Database.kt:17)
        at kotlin.SynchronizedLazyImpl.getValue(LazyJVM.kt:74)
        at org.jetbrains.exposed.sql.Database.getDialect(Database.kt)
        at org.jetbrains.exposed.sql.vendors.DefaultKt.getCurrentDialect(Default.kt:357)
        at org.jetbrains.exposed.sql.vendors.DefaultKt.getCurrentDialectIfAvailable(Default.kt:361)
        at org.jetbrains.exposed.sql.Column.getOnDelete$exposed_core(Column.kt:18)

Hi @AdityaAnand1 Any idea about how to fix this issue?