In 2020, I wrote a lot of articles on accident solution, which I did not rack my brains to come up with, but really encountered these problems. It is meaningful to record it and share it with others.

The accident background

First of all, let’s look at the image below, which IS a screenshot I took from CAT.

From the error, we can only analyze that the Rpc request was successful and returned, because it has gone to the deserialization step.

错 误 : Could not initalize class XXXXX. 错 误 : Could not initalize class XXXXX.

As a caller, although I saw a clear error, I still had to take a rigorous attitude to troubleshoot the problem and confirm whether there was a problem with the service provider. I confirmed with my colleagues that the service provider was ok and could invoke normally through Telnet.

Ok, so far on the background explained clearly, can not find this hidden Bug on each show their skills.

Arthas showed his talents

To be efficient, you must have good tools! Arthas stepped forward, offered himself up, didn’t have to.

First, use the SC command to view the JVM loaded classes to see if the class that cannot be instantiated was successfully loaded.

Sc-d class full path (Print the details of the class)

The class information is printed out to prove that the class was loaded.

And then print the fields in the class, see if anything’s missing

Sc-d-f class full path (printOut of theOf the classFieldinformation)

Error: create an object, and then reflect all field information. Error: create an object, and reflect all field information.

Is that the end of it? How is that possible? You’re not off duty yet. Keep going…

Now I began to wonder if there was something wrong with this class and started decomcompiling it using jad, another arthas command.

The jad command decompiles the actual class byte code running in the JVM into Java code to help us understand the business logic and to see if the code is consistent with the native code.

**jad –source-only ** class full path

I wondered if I was using the jad –source-only java.lang.String command incorrectly. Then I tried jad –source-only java.lang.String.

Then I remembered that there was another re-define command that I could use to load an external.class file and see if I could load it in. I unzipped the jar I relied on in the lib directory and used Re-define to load the undecompile class.

It is an invalid class. I have tried many times but failed to make this class show up.

In the end, I had no choice but to bring this class to the local location, drag it into IDEA, and decomcompile it. After comparing the code, it is exactly the same as that in git repository, so there is no problem of jar package damage.

About to reveal the truth

The valid leads so far are as follows:

  • Class is loaded but cannot be instantiated
  • With native decompilation, the code is complete

In this situation, the more I need to calm down and think, so I looked at the source code again and found that this class references an external custom exception class.

Then I use sc-D to check the information of this class and tell me that it does not exist. Finally I understand.

Looking at the diagram above, project A relies on the API, which in turn relies on Common, which in turn relies on A number of other tripartite Jar packages.

Since project A and Common rely on A tripartite Jar package conflict, so project A has simply excluded Common, the conflict is resolved.

During the RPC call, the data response to the request needs to be deserialized into an object. This time, the object creation fails because the class depends on some external class, but it is not loaded in the current project, so an error is reported.

conclusion

The problem this time boils down to the fact that you don’t expect an API to rely on other modules, and the API itself should be concise as an RPC call client.

In fact, during the process of exclusion, only the conflicting three-party JARS should be exclusion, and the whole Common should not be exclusion.

Arthas is a good helper. Arthas allows us to further eliminate problems with classes loaded after the program starts and further narrow the scope.

If you are interested, you can pay attention to my wechat public number, Simtiandi, and read more technical articles for the first time. I also have some open source code on GitHub github.com/yinjihuan