我正在尝试使用 jenkins 管道中的以下类序列化和反序列化一个 groovy 对象。
SerializationUtil.groovy
package com.sample;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* A simple class with generic serialize and deserialize method implementations
*/
public class SerializationUtil {
// deserialize to Object from given file
public static Object deserialize(String fileName) throws IOException,
ClassNotFoundException {
FileInputStream fis = new FileInputStream(fileName);
ObjectInputStream ois = new ObjectInputStream(fis);
Object obj = ois.readObject();
ois.close();
System.out.println(obj);
return obj;
}
// serialize the given object and save it to file
public static void serialize(Object obj, String fileName)
throws IOException {
FileOutputStream fos = new FileOutputStream(fileName);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(obj);
fos.close();
}
}
Test.groovy
package com.sample;
public class Test implements Serializable {
String key;
public String getKey() {
return key;
}
public void setKey(String key) {
this.key = key;
}
@Override
public String toString() {
return "com.sample.Test{" +
"key='" + key + '\'' +
'}';
}
}
Jenkins pipeline script
Test test = new Test()
test.setKey("sample")
SerializationUtil.serialize(test,"/temp/test.txt")
Test test2 = SerializationUtil.deserialize("/temp/test.txt")
我能够序列化对象但不能反序列化。我收到以下异常。
java.lang.ClassNotFoundException: com.sample.Test
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.eclipse.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:543)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:628)
at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1620)
at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1521)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1781)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)
at sun.reflect.GeneratedMethodAccessor8862.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:93)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1213)
at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1022)
at org.codehaus.groovy.runtime.callsite.PojoMetaClassSite.call(PojoMetaClassSite.java:47)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:48)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:113)
at com.cloudbees.groovy.cps.sandbox.DefaultInvoker.methodCall(DefaultInvoker.java:20)
at com.sample.SerializationUtil.deserialize(SerializationUtil.groovy:20)
从异常中,我可以看到 GroovyClassLoader 没有被调用,我认为这可能是问题所在。
最佳答案
问题是,正如您已经确定的,没有 GroovyClassLoader 参与其中……特别是不知道您当前的类的人。
虽然 ObjectOutputStream 并不真正关心用 ObjectInputStream 定义的类是什么类加载器,但在这里必须做出假设,因为它需要创建一个实例。从跟踪来看,为创建对象实例而选择的“最近”类加载器将是包含 groovy 运行时的类加载器。遗憾的是,这是 Groovy 的一个常见问题,因为在 Java 中不断引入越来越多的调用者敏感逻辑。
无论如何,如果你也有这样的东西(ScriptLoaderObjectInputStream.groovy):
class ScriptLoaderObjectInputStream extends ObjectInputStream {
ScriptLoaderObjectInputStream(InputStream str) { super(str) }
protected Class resolveClass(ObjectStreamClass desc) {
return this.class.classLoader.loadClass(desc.getName())
}
}
并用这个替换您对 ObjectInputStream 的使用,它应该可以工作。它应该可以工作,因为这也是一个脚本文件,并且生成的类应该具有与其他生成的类相同的类加载器。
为了进一步阅读,我发现这个很不错:https://rsankarx.wordpress.com/2012/06/08/java-serialization-classloaders/
免责声明:我在这里写的,没有 IDE,没有拼写检查,也没有涉及测试。
关于java - 无法加载 groovy 类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62166870/