alibaba / alibaba/arthas

Jad / mc / redefine : missed classes dependencies when using multiple classloaders

Open
#655 7 comments 0 reactions 0 assignees View on GitHub
Dominant language
Java
Stars
37.5k
Forks
7.6k
Avg merge
1d 22h
Merged PRs (30d)
4

Description

### Environment

* Arthas version: 3.1.0
* Operating System version: OSX 10.14.4
* Java version of target JVM: Oracle JDK 1.8.0_201
* Java version of JVM used to attach: Oracle JDK 1.8.0_201

### Steps to reproduce

I'm using uding this tool on an OSGi java application (based on Apache Felix). When working with jad I can see that lots of classes are not loaded:

```
$ jad com.mycompany.osgi.mycustmr.myprj.messaging.impl.MyPrjMessagingSubscriber

ClassLoader:
+-com.mycompany.osgi.mycustmr.myprj.messaging [96]

Location:
/Users/andreadilisio/Documents/projects/mycustmr/MyPrj/git-repo/com.mycompany.osgi.mycustmr.myprj.messaging/

/*
* Decompiled with CFR 0_132.
*
* Could not load the following classes:
* com.header.mbcdm.ErrorType
* com.header.mbcdm.HeaderType
* com.mbms.mbcdm.cdmservices_dev.CDMServicesDevPortType
* com.util.mbcdm.SMSAlertReqType
* com.util.mbcdm.SMSAlertReqType$SMSDetails
* com.util.mbcdm.sendsmsmessage.EAIServices
* com.util.mbcdm.sendsmsmessage.EAIServices$Body
* com.mycompany.osgi.common.PlatformThreadContext
* com.mycompany.osgi.core.config.agent.IConfigurationAgent
* com.mycompany.osgi.core.logging.ILoggingService
* com.mycompany.osgi.exception.mycompanyException
* com.mycompany.osgi.foundation.messaging.IMessagingService
* com.mycompany.osgi.mycustmr.myprj.common.exception.MyPrjRuntimeException
* com.mycompany.osgi.mycustmr.myprj.core.dao.SegmentSmsServiceIdDao
* com.mycompany.osgi.mycustmr.myprj.core.dao.UserDao
* com.mycompany.osgi.mycustmr.myprj.core.middleware.IMiddlewareConnectorService
* com.mycompany.osgi.mycustmr.myprj.core.persistence.IMyPrjPersistenceService
* com.mycompany.osgi.mycustmr.myprj.entity.core.model.NotificationType
* com.mycompany.osgi.mycustmr.myprj.entity.core.model.SegmentSmsServiceId
* com.mycompany.osgi.mycustmr.myprj.entity.core.model.TransactionHistory
* com.mycompany.osgi.mycustmr.myprj.entity.core.model.User
* com.mycompany.osgi.mycustmr.myprj.messaging.common.MyPrjMessageType
* com.mycompany.osgi.mycustmr.myprj.messaging.historytimeline.TimelineManager
* com.mycompany.osgi.mycustmr.myprj.messaging.messages.UserMessageManager
* com.mycompany.osgi.mycustmr.myprj.messaging.notification.INotificationPreferenceManager
* com.mycompany.osgi.mycustmr.myprj.messaging.notification.NotificationPreferenceManagerFactory
* com.mycompany.osgi.util.StringUtils
* org.osgi.service.event.Event
* org.osgi.service.event.EventHandler
* org.slf4j.Logger
*/
package com.mycompany.osgi.mycustmr.myprj.messaging.impl;

import com.header.mbcdm.ErrorType;
import com.header.mbcdm.HeaderType;
import com.mbms.mbcdm.cdmservices_dev.CDMServicesDevPortType;
import com.util.mbcdm.SMSAlertReqType;
import com.util.mbcdm.sendsmsmessage.EAIServices;
```
I guess this is due to the fact that the referenced classes are coming from other OSGi bundles, that is different classloaders. In fact:
```
$ sc -d com.mycompany.osgi.mycustmr.myprj.messaging.impl.MyPrjMessagingSubscriber
class-info com.mycompany.osgi.mycustmr.myprj.messaging.impl.MyPrjMessagingSubscriber
code-source /Users/andreadilisio/Documents/projects/mycustmr/myprj/git-repo/com.mycompany.osgi.mycustmr.myprj.messaging/
name com.mycompany.osgi.mycustmr.myprj.messaging.impl.MyPrjMessagingSubscriber
isInterface false
isAnnotation false
isEnum false
isAnonymousClass false
isArray false
isLocalClass false
isMemberClass false
isPrimitive false
isSynthetic false
simple-name MyPrjMessagingSubscriber
modifier public
annotation
interfaces org.osgi.service.event.EventHandler
super-class +-java.lang.Object
class-loader +-com.mycompany.osgi.mycustmr.myprj.messaging [96]
classLoaderHash 4124a739

$ sc -d com.header.mbcdm.ErrorType
class-info com.header.mbcdm.ErrorType
code-source /Users/andreadilisio/Documents/projects/mycustmr/myprj/git-repo/com.mycompany.osgi.mycustmr.myprj.core.middleware/
name com.header.mbcdm.ErrorType
isInterface false
isAnnotation false
isEnum false
isAnonymousClass false
isArray false
isLocalClass false
isMemberClass false
isPrimitive false
isSynthetic false
simple-name ErrorType
modifier public
annotation javax.xml.bind.annotation.XmlAccessorType,javax.xml.bind.annotation.XmlType
interfaces
super-class +-java.lang.Object
class-loader +-com.mycompany.osgi.mycustmr.myprj.core.middleware [89]
classLoaderHash 569c3bd2

$ sc -d com.mycompany.osgi.common.PlatformThreadContext
class-info com.mycompany.osgi.common.PlatformThreadContext
code-source /Users/andreadilisio/Documents/projects/mycustmr/myprj/git-repo/com.mycompany.osgi.mycustmr.myprj.pkg/patches/com.mycompany.osgi.common-2.0.0.patch2.jar
name com.mycompany.osgi.common.PlatformThreadContext
isInterface false
isAnnotation false
isEnum false
isAnonymousClass false
isArray false
isLocalClass false
isMemberClass false
isPrimitive false
isSynthetic false
simple-name PlatformThreadContext
modifier public
annotation
interfaces
super-class +-java.lang.Object
class-loader +-com.mycompany.osgi.common [18]
classLoaderHash 26fd192e
```
This would not be an issue for inspection purpose only... it becomes an issue when trying to redefine a class.

### Expected Result

Being able to use *mc* and *redefine* command on the above mentioned class.

### Actual Result
Currently i'm not able to use the memory complier due to missed dependecies
```
$ mc /tmp/MyPrjMessagingSubscriber.java
Memory compiler error, exception message: Compilation Error
line: 38 , message: package com.header.mbcdm does not exist ,
line: 39 , message: package com.header.mbcdm does not exist ,
[...]
line: 79 , message: cannot find symbol
symbol: class EventHandler ,
line: 80 , message: cannot find symbol
symbol: class Logger
location: class com.mycompany.osgi.mycstmr.myprj.messaging.impl.MyPrjMessagingSubscriber ,
```

Is there a way to overcome this issue ?

Contributor guide

Open the contributing guide

Research direction

Start by tracing the jad, mc, and redefine command paths involved in resolving classes across the classloaders shown by sc -d. Reproduce the issue with the reported OSGi application or an equivalent multiple-classloader setup, then verify that mc can compile the decompiled class and redefine can apply it with its referenced dependencies available.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
devtools
Issue type
Bug
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.