spring-projects / spring-loaded

Java agent that enables class reloading in a running JVM
Apache License 2.0
2.72k stars 515 forks source link

Unexpected problem transforming call sites with HikariCP #77

Open axelfontaine opened 10 years ago

axelfontaine commented 10 years ago

Environment:

Stacktrace:

java.lang.IllegalStateException: null
    at org.springsource.loaded.MethodInvokerRewriter$RewriteClassAdaptor$RewritingMethodAdapter.visitInvokeDynamicInsn(MethodInvokerRewriter.java:997)
    at sl.org.objectweb.asm.ClassReader.a(Unknown Source)
    at sl.org.objectweb.asm.ClassReader.b(Unknown Source)
    at sl.org.objectweb.asm.ClassReader.accept(Unknown Source)
    at sl.org.objectweb.asm.ClassReader.accept(Unknown Source)
    at org.springsource.loaded.MethodInvokerRewriter.rewrite(MethodInvokerRewriter.java:332)
    at org.springsource.loaded.MethodInvokerRewriter.rewrite(MethodInvokerRewriter.java:96)
    at org.springsource.loaded.TypeRegistry.methodCallRewriteUseCacheIfAvailable(TypeRegistry.java:830)
    at org.springsource.loaded.agent.SpringLoadedPreProcessor.preProcess(SpringLoadedPreProcessor.java:317)
    at org.springsource.loaded.agent.ClassPreProcessorAgentAdapter.transform(ClassPreProcessorAgentAdapter.java:102)
    at sun.instrument.TransformerManager.transform(TransformerManager.java:188)
    at sun.instrument.InstrumentationImpl.transform(InstrumentationImpl.java:428)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:760)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:455)
    at java.net.URLClassLoader.access$100(URLClassLoader.java:73)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:367)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:360)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at com.zaxxer.hikari.HikariDataSource.<init>(HikariDataSource.java:80)

Offending code:

HikariConfig config = new HikariConfig();
config.setDriverClassName(org.postgresql.Driver.class.getName());
config.setJdbcUrl(dbUrl);
config.setUsername(dbUser);
config.setPassword(dbPassword);
config.setMaximumPoolSize(15);
new HikariDataSource(config); //this line triggers the error
brettwooldridge commented 10 years ago

It appears that Spring-loaded has some issue with Java 8 lambas. The line of code that is blowing up has a more descriptive message in the master branch:

@Override
public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) {
    // TODO *shudder* what about invoke dynamic calls that target reflective APIs
    int classId = typeRegistry.getTypeIdFor(slashedclassname, true);
    if (classId==-1) {
        throw new IllegalStateException("Unable to find classId for "+slashedclassname+" referenced from invokedynamic in "+this.methodname+"()");
    }

    // Initially only rewriting use of INVOKEDYNAMIC to support Lambda execution
    // TODO support the more general invokedynamic usage

The class being loaded that is causing Sprint-loaded grief is com.zaxxer.hikari.pool.HikariPool, and it does indeed use lamdas in the Java 8 incarnation.

If you want to work around this issue, drop back to using the HikariCP-java6 artifact, it is functionally the same as the Java 8 HikariCP artifact.