You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@activemq.apache.org by "Calvin Moody (JIRA)" <ji...@apache.org> on 2013/09/27 21:44:04 UTC

[jira] [Updated] (AMQ-4746) Applet ClassLoader Problems

     [ https://issues.apache.org/jira/browse/AMQ-4746?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Calvin Moody updated AMQ-4746:
------------------------------

          Description: 
In ClassLoadingAwareObjectInputStream.java the  load() method makes a call to Class.forName().

For the primitive types (int, boolean, etc.) this would result in a call similar to:
    Class.forName("int", false, loader); //Where loader is the Applet2ClassLoader

Since Applet2ClassLoader is a URLClassLoader and "int.class" is not in the jar cache it pulled down from the server at the start of application, it is going to try and go to the server to resolve this class.
In the event of a network failure, this will result in the ClassLoader having to wait for the socket timeout. (see stacktrace below) Once this socket timeout occurs, the load() method then attempts to lookup the class in the primitive HashMap that is statically initialized. This returns the class for the int and the deserialization continues on.

At first it seemed like the messages were failing to be received but it turned out they were just taking a very long time to be deserialized. This problem can be avoided by changing the order in which ClassLoadingAwareObjectInputStream tries to resolve the class. 

Here is the change I made to the load() method: http://activemq.2283324.n4.nabble.com/Applet-Class-Loader-Problems-td4671835.html 

Stacktrace: 
Name: ActiveMQ Session Task-96
State: RUNNABLE
Total blocked: 19  Total waited: 77

Stack trace:
 java.net.TwoStacksPlainSocketImpl.socketConnect(Native Method)
java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
   - locked java.net.TwoStacksPlainSocketImpl@1dcac73
java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
java.net.AbstractPlainSocketImpl.connect(Unknown Source)
java.net.PlainSocketImpl.connect(Unknown Source)
java.net.SocksSocketImpl.connect(Unknown Source)
java.net.Socket.connect(Unknown Source)
sun.security.ssl.SSLSocketImpl.connect(Unknown Source)
sun.net.NetworkClient.doConnect(Unknown Source)
sun.net.www.http.HttpClient.openServer(Unknown Source)
sun.net.www.http.HttpClient.openServer(Unknown Source)
   - locked sun.net.www.protocol.https.HttpsClient@bdc77d
sun.net.www.protocol.https.HttpsClient.<init>(Unknown Source)
sun.net.www.protocol.https.HttpsClient.New(Unknown Source)
sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(Unknown Source)
sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
   - locked sun.net.www.protocol.https.DelegateHttpsURLConnection@1c204d7
java.net.HttpURLConnection.getResponseCode(Unknown Source)
sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
sun.plugin2.applet.Applet2ClassLoader.getBytes(Unknown Source)
sun.plugin2.applet.Applet2ClassLoader.access$000(Unknown Source)
sun.plugin2.applet.Applet2ClassLoader$1.run(Unknown Source)
java.security.AccessController.doPrivileged(Native Method)
sun.plugin2.applet.Applet2ClassLoader.findClass(Unknown Source)
sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Unknown Source)
sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
   - locked sun.plugin2.applet.Applet2ClassLoader@1fe96f2
sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
   - locked sun.plugin2.applet.Applet2ClassLoader@1fe96f2
java.lang.ClassLoader.loadClass(Unknown Source)
java.lang.Class.forName0(Native Method)
java.lang.Class.forName(Unknown Source)
org.apache.activemq.util.ClassLoadingAwareObjectInputStream.load(ClassLoadingAwareObjectInputStream.java:77)
org.apache.activemq.util.ClassLoadingAwareObjectInputStream.resolveClass(ClassLoadingAwareObjectInputStream.java:46)
java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
java.io.ObjectInputStream.readClassDesc(Unknown Source)
java.io.ObjectInputStream.readClass(Unknown Source)
java.io.ObjectInputStream.readObject0(Unknown Source)
java.io.ObjectInputStream.readArray(Unknown Source)
java.io.ObjectInputStream.readObject0(Unknown Source)
java.io.ObjectInputStream.defaultReadFields(Unknown Source)
java.io.ObjectInputStream.readSerialData(Unknown Source)
java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
java.io.ObjectInputStream.readObject0(Unknown Source)
java.io.ObjectInputStream.defaultReadFields(Unknown Source)
java.io.ObjectInputStream.readSerialData(Unknown Source)
java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
java.io.ObjectInputStream.readObject0(Unknown Source)
java.io.ObjectInputStream.readObject(Unknown Source)
org.apache.activemq.command.ActiveMQObjectMessage.getObject(ActiveMQObjectMessage.java:185)
com.mypackage.MyClass$2.processObjectMessage(MyClass.java:386)
com.mypackage.JMSMessageProcessor.onMessage(JMSMessageProcessor.java:29)
   - locked com.mypackage.MyClass$2@9595d2
org.apache.activemq.ActiveMQMessageConsumer.dispatch(ActiveMQMessageConsumer.java:1321)
   - locked java.lang.Object@40c537
org.apache.activemq.ActiveMQSessionExecutor.dispatch(ActiveMQSessionExecutor.java:131)
org.apache.activemq.ActiveMQSessionExecutor.iterate(ActiveMQSessionExecutor.java:202)
org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:129)
org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:47)
java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
java.lang.Thread.run(Unknown Source) 



  was:
In ClassLoadingAwareObjectInputStream.java the  load() method makes a call to Class.forName().

For the primitive types (int, boolean, etc.) this would result in a call similar to:
    Class.forName("int", false, loader); //Where loader is the Applet2ClassLoader

Since Applet2ClassLoader is a URLClassLoader and "int.class" is not in the jar cache it pulled down from the server at the start of application, it is going to try and go to the server to resolve this class.
In the event of a network failure, this will result in the ClassLoader having to wait for the socket timeout. (see stacktrace in previous post) Once this socket timeout occurs, the load() method then attempts to lookup the class in the primitive HashMap that is statically initialized. This returns the class for the int and the deserialization continues on.

At first it seemed like the messages were failing to be received but it turned out they were just taking a very long time to be deserialized. This problem can be avoided by changing the order in which ClassLoadingAwareObjectInputStream tries to resolve the class. 

Here is the change I made to the load() method: http://activemq.2283324.n4.nabble.com/Applet-Class-Loader-Problems-td4671835.html 



    Affects Version/s: 5.8.0
    
> Applet ClassLoader Problems
> ---------------------------
>
>                 Key: AMQ-4746
>                 URL: https://issues.apache.org/jira/browse/AMQ-4746
>             Project: ActiveMQ
>          Issue Type: Bug
>          Components: JMS client
>    Affects Versions: 5.7.0, 5.8.0
>         Environment: Windows 7, Java 1.7 or 1.6, Applet
>            Reporter: Calvin Moody
>              Labels: ClassLoader
>   Original Estimate: 24h
>  Remaining Estimate: 24h
>
> In ClassLoadingAwareObjectInputStream.java the  load() method makes a call to Class.forName().
> For the primitive types (int, boolean, etc.) this would result in a call similar to:
>     Class.forName("int", false, loader); //Where loader is the Applet2ClassLoader
> Since Applet2ClassLoader is a URLClassLoader and "int.class" is not in the jar cache it pulled down from the server at the start of application, it is going to try and go to the server to resolve this class.
> In the event of a network failure, this will result in the ClassLoader having to wait for the socket timeout. (see stacktrace below) Once this socket timeout occurs, the load() method then attempts to lookup the class in the primitive HashMap that is statically initialized. This returns the class for the int and the deserialization continues on.
> At first it seemed like the messages were failing to be received but it turned out they were just taking a very long time to be deserialized. This problem can be avoided by changing the order in which ClassLoadingAwareObjectInputStream tries to resolve the class. 
> Here is the change I made to the load() method: http://activemq.2283324.n4.nabble.com/Applet-Class-Loader-Problems-td4671835.html 
> Stacktrace: 
> Name: ActiveMQ Session Task-96
> State: RUNNABLE
> Total blocked: 19  Total waited: 77
> Stack trace:
>  java.net.TwoStacksPlainSocketImpl.socketConnect(Native Method)
> java.net.AbstractPlainSocketImpl.doConnect(Unknown Source)
>    - locked java.net.TwoStacksPlainSocketImpl@1dcac73
> java.net.AbstractPlainSocketImpl.connectToAddress(Unknown Source)
> java.net.AbstractPlainSocketImpl.connect(Unknown Source)
> java.net.PlainSocketImpl.connect(Unknown Source)
> java.net.SocksSocketImpl.connect(Unknown Source)
> java.net.Socket.connect(Unknown Source)
> sun.security.ssl.SSLSocketImpl.connect(Unknown Source)
> sun.net.NetworkClient.doConnect(Unknown Source)
> sun.net.www.http.HttpClient.openServer(Unknown Source)
> sun.net.www.http.HttpClient.openServer(Unknown Source)
>    - locked sun.net.www.protocol.https.HttpsClient@bdc77d
> sun.net.www.protocol.https.HttpsClient.<init>(Unknown Source)
> sun.net.www.protocol.https.HttpsClient.New(Unknown Source)
> sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(Unknown Source)
> sun.net.www.protocol.http.HttpURLConnection.plainConnect(Unknown Source)
> sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(Unknown Source)
> sun.net.www.protocol.http.HttpURLConnection.getInputStream(Unknown Source)
>    - locked sun.net.www.protocol.https.DelegateHttpsURLConnection@1c204d7
> java.net.HttpURLConnection.getResponseCode(Unknown Source)
> sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(Unknown Source)
> sun.plugin2.applet.Applet2ClassLoader.getBytes(Unknown Source)
> sun.plugin2.applet.Applet2ClassLoader.access$000(Unknown Source)
> sun.plugin2.applet.Applet2ClassLoader$1.run(Unknown Source)
> java.security.AccessController.doPrivileged(Native Method)
> sun.plugin2.applet.Applet2ClassLoader.findClass(Unknown Source)
> sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Unknown Source)
> sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
>    - locked sun.plugin2.applet.Applet2ClassLoader@1fe96f2
> sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
>    - locked sun.plugin2.applet.Applet2ClassLoader@1fe96f2
> java.lang.ClassLoader.loadClass(Unknown Source)
> java.lang.Class.forName0(Native Method)
> java.lang.Class.forName(Unknown Source)
> org.apache.activemq.util.ClassLoadingAwareObjectInputStream.load(ClassLoadingAwareObjectInputStream.java:77)
> org.apache.activemq.util.ClassLoadingAwareObjectInputStream.resolveClass(ClassLoadingAwareObjectInputStream.java:46)
> java.io.ObjectInputStream.readNonProxyDesc(Unknown Source)
> java.io.ObjectInputStream.readClassDesc(Unknown Source)
> java.io.ObjectInputStream.readClass(Unknown Source)
> java.io.ObjectInputStream.readObject0(Unknown Source)
> java.io.ObjectInputStream.readArray(Unknown Source)
> java.io.ObjectInputStream.readObject0(Unknown Source)
> java.io.ObjectInputStream.defaultReadFields(Unknown Source)
> java.io.ObjectInputStream.readSerialData(Unknown Source)
> java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
> java.io.ObjectInputStream.readObject0(Unknown Source)
> java.io.ObjectInputStream.defaultReadFields(Unknown Source)
> java.io.ObjectInputStream.readSerialData(Unknown Source)
> java.io.ObjectInputStream.readOrdinaryObject(Unknown Source)
> java.io.ObjectInputStream.readObject0(Unknown Source)
> java.io.ObjectInputStream.readObject(Unknown Source)
> org.apache.activemq.command.ActiveMQObjectMessage.getObject(ActiveMQObjectMessage.java:185)
> com.mypackage.MyClass$2.processObjectMessage(MyClass.java:386)
> com.mypackage.JMSMessageProcessor.onMessage(JMSMessageProcessor.java:29)
>    - locked com.mypackage.MyClass$2@9595d2
> org.apache.activemq.ActiveMQMessageConsumer.dispatch(ActiveMQMessageConsumer.java:1321)
>    - locked java.lang.Object@40c537
> org.apache.activemq.ActiveMQSessionExecutor.dispatch(ActiveMQSessionExecutor.java:131)
> org.apache.activemq.ActiveMQSessionExecutor.iterate(ActiveMQSessionExecutor.java:202)
> org.apache.activemq.thread.PooledTaskRunner.runTask(PooledTaskRunner.java:129)
> org.apache.activemq.thread.PooledTaskRunner$1.run(PooledTaskRunner.java:47)
> java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
> java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
> java.lang.Thread.run(Unknown Source) 

--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: http://www.atlassian.com/software/jira