address issue #1119 (serialization with protected/private constructor) (#1181)

* address issue #1119 (serialization with protected/private constructor)

* remove an unnecessary step in findNoArgConstructor()

* use getDeclaredConstructor() in place of the for-loop

* simplify by throwing the exception in findNoArgContructor()
fix-openal-soft-deadlink
Stephen Gold 5 years ago committed by GitHub
parent 909ea30216
commit 5eaf653de9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 41
      jme3-core/src/main/java/com/jme3/export/SavableClassUtil.java
  2. 11
      jme3-core/src/plugins/java/com/jme3/export/binary/BinaryImporter.java
  3. 4
      jme3-plugins/src/xml/java/com/jme3/export/xml/DOMInputCapsule.java

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* Copyright (c) 2009-2019 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -36,7 +36,9 @@ import com.jme3.effect.shapes.*;
import com.jme3.material.MatParamTexture;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@ -161,16 +163,19 @@ public class SavableClassUtil {
* @return the Savable instance of the class.
* @throws InstantiationException thrown if the class does not have an empty constructor.
* @throws IllegalAccessException thrown if the class is not accessable.
* @throws java.lang.reflect.InvocationTargetException
* @throws ClassNotFoundException thrown if the class name is not in the classpath.
* @throws IOException when loading ctor parameters fails
*/
public static Savable fromName(String className) throws InstantiationException,
IllegalAccessException, ClassNotFoundException, IOException {
public static Savable fromName(String className)
throws ClassNotFoundException, IllegalAccessException,
InstantiationException, InvocationTargetException {
className = remapClass(className);
Constructor noArgConstructor = findNoArgConstructor(className);
noArgConstructor.setAccessible(true);
try {
return (Savable) Class.forName(className).newInstance();
} catch (InstantiationException e) {
return (Savable) noArgConstructor.newInstance();
} catch (InvocationTargetException | InstantiationException e) {
Logger.getLogger(SavableClassUtil.class.getName()).log(
Level.SEVERE, "Could not access constructor of class ''{0}" + "''! \n"
+ "Some types need to have the BinaryImporter set up in a special way. Please doublecheck the setup.", className);
@ -184,6 +189,7 @@ public class SavableClassUtil {
}
public static Savable fromName(String className, List<ClassLoader> loaders) throws InstantiationException,
InvocationTargetException, NoSuchMethodException,
IllegalAccessException, ClassNotFoundException, IOException {
if (loaders == null) {
return fromName(className);
@ -208,4 +214,25 @@ public class SavableClassUtil {
return fromName(className);
}
/**
* Use reflection to gain access to the no-arg constructor of the named
* class.
*
* @return the pre-existing constructor (not null)
*/
private static Constructor findNoArgConstructor(String className)
throws ClassNotFoundException, InstantiationException {
Class clazz = Class.forName(className);
Constructor result;
try {
result = clazz.getDeclaredConstructor();
} catch (NoSuchMethodException e) {
throw new InstantiationException(
"Loading requires a no-arg constructor, but class "
+ className + " lacks one.");
}
return result;
}
}

@ -345,16 +345,7 @@ public final class BinaryImporter implements JmeImporter {
return out;
} catch (IOException e) {
logger.logp(Level.SEVERE, this.getClass().toString(), "readObject(int id)", "Exception", e);
return null;
} catch (ClassNotFoundException e) {
logger.logp(Level.SEVERE, this.getClass().toString(), "readObject(int id)", "Exception", e);
return null;
} catch (InstantiationException e) {
logger.logp(Level.SEVERE, this.getClass().toString(), "readObject(int id)", "Exception", e);
return null;
} catch (IllegalAccessException e) {
} catch (Exception e) {
logger.logp(Level.SEVERE, this.getClass().toString(), "readObject(int id)", "Exception", e);
return null;
}

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009-2012 jMonkeyEngine
* Copyright (c) 2009-2019 jMonkeyEngine
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -38,6 +38,7 @@ import com.jme3.export.SavableClassUtil;
import com.jme3.util.BufferUtils;
import com.jme3.util.IntMap;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.nio.ByteBuffer;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
@ -962,6 +963,7 @@ public class DOMInputCapsule implements InputCapsule {
private Savable readSavableFromCurrentElem(Savable defVal) throws
InstantiationException, ClassNotFoundException,
NoSuchMethodException, InvocationTargetException,
IOException, IllegalAccessException {
Savable ret = defVal;
Savable tmp = null;

Loading…
Cancel
Save