Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javassist NotFoundException when getting java.io.Serializable with JDK9

I have the following code:

private static CtClass resolveCtClass(String clazz) throws NotFoundException {
  ClassPool pool = ClassPool.getDefault();
  return pool.get( clazz );
}

When running under JDK8, if this method is called using java.io.Serializable, it works, but when running under the JDK9 environment, it throws the NotFoundException.

Is there something I overlooked here?

like image 413
Naros Avatar asked Jun 18 '16 00:06

Naros


People also ask

What is NotSerializableException in Java?

His main interests include distributed systems, storage systems, file systems, and operating systems. In this tutorial we will discuss about NotSerializableException in Java. The exception is thrown when an instance of a class must implement the Serializable interface.

What does notfoundexception mean in Java?

public class NotFoundException extends java.lang.Exception Signals that something could not be found. NotFoundException ​ (java.lang.String msg, java.lang.Exception e) public NotFoundException​ (java.lang.String msg, java.lang.Exception e)

What is the latest version of the library for Java 9?

If you look at their releases page on GitHub it wasn't until version 3.22.0-GA that the library became compatible with Java 9. That version is also outdated, however, as their latest version (as of writing this answer) is 3.23.1-GA. Change your dependency declaration to use the latest version and your issue should be solved.

What is serialization in Java and how to use it?

Serialization in Java is a mechanism of writing the state of an object into a byte-stream. It is mainly used in Hibernate, RMI, JPA, EJB, and JMS technologies.


2 Answers

This does no longer happen with the current EA builds of Java 9. Class files are now always locatable even if they are encapsulated in a module.

This is a consequence of Java 9's module encapsulation where non-exported resources are no longer available via the ClassLoader API. Under the covers, Javassist calls

ClassLoader.getSystemClassLoader().findResource("java/io/Serializable.class");

to get hold of the class file for Serializable. It then parses this class file and represents the information similarly to the Java reflection API but without loading the class such that it can be edited prior to loading it.

Until Java 8, this class file was accessible as most class loaders rely on looking up a class file before loading it such that the above call returned a URL pointing to the file. Since Java 9, resources of named modules are only available via the new API method findResource(String, String) where the second arguments names the module of that class.

The short answer is: Javassist does no longer work with Java 9 and none of its dependant projects will. This is a known issue with the current Java 9 implementation and will hopefully be fixed prior to release.

like image 113
Rafael Winterhalter Avatar answered Sep 23 '22 23:09

Rafael Winterhalter


(I never used Javassist so I'm just shooting in the dark, here...)

The documentation of ClassPool says:

If get() is called on this object, it searches various sources represented by ClassPath to find a class file and then it creates a CtClass object representing that class file.

This seems to be bound to the concept of the class path. Looking at ClassPath and CtClass supports that assumption.

If that is the case, then Javassist might just not be fit to look into JDK 9's brand new modules.

If my guess is correct, you should not be able to get any JDK class from the pool. This should be easily verifiable.

like image 35
Nicolai Parlog Avatar answered Sep 22 '22 23:09

Nicolai Parlog