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

Checked exception is thrown by Class.newInstance() despite there is no such exception in method definition #91

Open oleksii-sl opened 10 years ago

oleksii-sl commented 10 years ago

Hello,

I see that not all classes are preprocessed and in such case I see something like:

INFO: WhyNotReloadable? The type javax/naming/CommunicationException is using a package name 'javax/' which is considered infrastructure and types within it are not made reloadable

Also I see that WL classes are preprocessed and as a consequence of (invalid?) processing I get following error:

INFO: SpringLoaded preprocessing: classname=weblogic/utils/NestedThrowable$Util classloader=Launcher$AppClassLoader typeRegistry=TypeRegistry(id=1791140146,loader=sun.misc.Launcher$AppClassLoader)
<Nov 4, 2014 2:21:04 PM MSK> <Critical> <WebLogicServer> <BEA-000362> <Server failed. Reason: 

There are 1 nested errors:

weblogic.security.service.SecurityServiceRuntimeException: [Security:090877]Service Common JAASAuthenticationService unavailable, see exception text: java.lang.reflect.InvocationTargetException
    at weblogic.security.service.PrincipalAuthenticator.initialize(PrincipalAuthenticator.java:165)
    at weblogic.security.service.PrincipalAuthenticator.<init>(PrincipalAuthenticator.java:321)
    at weblogic.security.service.CommonSecurityServiceManagerDelegateImpl.doATN(CommonSecurityServiceManagerDelegateImpl.java:720)
    at weblogic.security.service.CommonSecurityServiceManagerDelegateImpl.initializeRealm(CommonSecurityServiceManagerDelegateImpl.java:504)
    at weblogic.security.service.CommonSecurityServiceManagerDelegateImpl.loadRealm(CommonSecurityServiceManagerDelegateImpl.java:840)
    at weblogic.security.service.CommonSecurityServiceManagerDelegateImpl.initializeRealms(CommonSecurityServiceManagerDelegateImpl.java:869)
    at weblogic.security.service.CommonSecurityServiceManagerDelegateImpl.initialize(CommonSecurityServiceManagerDelegateImpl.java:1028)
    at weblogic.security.service.SecurityServiceManager.initialize(SecurityServiceManager.java:875)
    at weblogic.security.SecurityService.start(SecurityService.java:141)
    at weblogic.t3.srvr.SubsystemRequest.run(SubsystemRequest.java:64)
    at weblogic.work.ExecuteThread.execute(ExecuteThread.java:201)
    at weblogic.work.ExecuteThread.run(ExecuteThread.java:173)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at org.springsource.loaded.ri.ReflectiveInterceptor.jlrConstructorNewInstance(ReflectiveInterceptor.java:1002)
    at org.springsource.loaded.ri.ReflectiveInterceptor.jlClassNewInstance(ReflectiveInterceptor.java:989)
    at weblogic.security.service.PrincipalAuthenticator.loadConfFileForJVM(PrincipalAuthenticator.java:211)
    at weblogic.security.service.PrincipalAuthenticator.initialize(PrincipalAuthenticator.java:137)
    ... 11 more
Caused by: java.lang.SecurityException: Unable to locate a login configuration
    at com.sun.security.auth.login.ConfigFile.<init>(ConfigFile.java:93)
    ... 19 more
Caused by: java.io.IOException: Unable to locate a login configuration
    at com.sun.security.auth.login.ConfigFile.init(ConfigFile.java:250)
    at com.sun.security.auth.login.ConfigFile.<init>(ConfigFile.java:91)
    ... 19 more

Is it possible to introduce property for filtering of classes? (e.g. if I put com.customcode.* - only packages with such prefix will be processed by spring loaded)

////Update Now I see that it's possible ( I checked the code ), but it should be documented I guess. I've applied filter and server starts much faster, but the error still reproduces. Weblogic version is 10.3.3, java version is 1.6, OS linux 64 bit. If I remove spring-loaded agent - everything is fine.

Update I turned on debug mode on internal jvm class: com.sun.security.auth.login.ConfigFile using -Djava.security.debug=all option And restarted server with and without spring-loaded agent. On the line where usually error occured with agent I see following:

scl: 
configfile:     Reading Policy from ~/.java.login.config
jar: beginEntry META-INF/MANIFEST.MF
jar: beginEntry META-INF/services/java.sql.Driver
jar: done with meta!
jar: nothing to verify!
scl:  getPermissions ProtectionDomain  (file:<path to jdbc>/ojdbc6.jar <no signer certificates>)
 sun.misc.Launcher$AppClassLoader@1242719c
 <no principals>
 java.security.Permissions@6fd33eef (
 (java.io.FilePermission <path to jdbc>/ojdbc6.jar read)
 (java.lang.RuntimePermission exitVM)
)

With turned on agent I see following debug lines from jvm class and same stacktrace following as above:

scl: 
configfile:     Reading Policy from ~/.java.login.config
<Nov 4, 2014 5:08:47 PM MSK> <Critical> <WebLogicServer> <BEA-000362> <Server failed. Reason: 
<STACKTRACE HERE>
oleksii-sl commented 10 years ago

I finally have found reason of such behavior. The code in WL do the following: getClass().getClassLoader().loadClass(configFile).newInstance() newInstance method throws only java.lang.Class#newInstance throws InstantiationException, IllegalAccessException It does not throw IllegalArgumentException, InvocationTargetException as java.lang.reflect.Constructor#newInstance does, it throws exception which occurred not wrapped with InvocationTargetException

Apparently on client side we don't expect InvocationTargetException and it's not handled. I've added following into org.springsource.loaded.ri.ReflectiveInterceptor#jlrConstructorNewInstance Line 1002:

            try {
                return c.newInstance(params);
            } catch (InvocationTargetException e) {
                throw (RuntimeException)e.getCause();
            }

Instead of just return c.newInstance(params); and the error missed.

After all I got another error, but I hope it's because of dev build ( I donwloaded master branch and applied fix of above issue ).

Caused By: java.lang.NullPointerException
        at org.springsource.loaded.ri.ReflectiveInterceptor.fixModifier(ReflectiveInterceptor.java:420)
        at org.springsource.loaded.ri.ReflectiveInterceptor.fixModifiers(ReflectiveInterceptor.java:415)
        at org.springsource.loaded.ri.ReflectiveInterceptor.jlClassGetDeclaredFields(ReflectiveInterceptor.java:1605)
        at weblogic.j2ee.dd.xml.BaseJ2eeAnnotationProcessor.getFields(BaseJ2eeAnnotationProcessor.java:1024)
        at weblogic.j2ee.dd.xml.BaseJ2eeAnnotationProcessor.getFields(BaseJ2eeAnnotationProcessor.java:1017)