From f07f8a3b8ddc238666ba710102a8e2e64e38c5bb Mon Sep 17 00:00:00 2001 From: marcus-talbot42 Date: Tue, 20 Sep 2022 14:28:41 +0200 Subject: [PATCH] Fix for issue with DynamicClassGeneratorHelper#getNeighbourClass(CtClass) - DynamicClassGeneratorHelper#getNeighbourClass(CtClass) would return null on some occasions. This was fixed by passing the base-class for the dynamic class to the constructor of GeneratedClass. The baseclass can be used as a substitute for the neighbour-class. - Updated CHANGELOG.md. --- CHANGELOG.md | 4 +- .../beanmapper/dynclass/ClassGenerator.java | 2 +- .../dynclass/DynamicClassGeneratorHelper.java | 36 ------------------ .../beanmapper/dynclass/GeneratedClass.java | 4 +- .../DynamicClassGeneratorHelperTest.java | 37 ------------------- 5 files changed, 6 insertions(+), 77 deletions(-) delete mode 100644 src/main/java/io/beanmapper/dynclass/DynamicClassGeneratorHelper.java delete mode 100644 src/test/java/io/beanmapper/dynclass/DynamicClassGeneratorHelperTest.java diff --git a/CHANGELOG.md b/CHANGELOG.md index f830e22f..628bf2e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,9 +15,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Issue [#137](https://github.com/42BV/beanmapper/issues/137) **https://github.com/42BV/beanmapper/issues/137**; Mapping a class with a getter that returns an Optional, would fail, as an Optional can typically not be mapped to the target class. Fixed implementing an OptionalToObjectConverter, which handles unpacking an Optional, and additionally delegates further conversion back to the BeanMapper. +- DynamicClassGeneratorHelper was removed, due to returning null, and replaced with passing the baseclass for a generated class immediately to the constructor + of GeneratedClass. -## [3.2.0] - 2022-09-15 +## [4.0.0] - 2022-09-15 ### Changed diff --git a/src/main/java/io/beanmapper/dynclass/ClassGenerator.java b/src/main/java/io/beanmapper/dynclass/ClassGenerator.java index 35b9c8f9..41f07454 100644 --- a/src/main/java/io/beanmapper/dynclass/ClassGenerator.java +++ b/src/main/java/io/beanmapper/dynclass/ClassGenerator.java @@ -42,7 +42,7 @@ public GeneratedClass createClass( Map baseFields = beanMatchStore.getBeanMatch( strictMappingProperties.createBeanPair(baseClass, Object.class) ).getSourceNodes(); - return new GeneratedClass(createClass(baseClass, baseFields, displayNodes, strictMappingProperties)); + return new GeneratedClass(createClass(baseClass, baseFields, displayNodes, strictMappingProperties), baseClass); } private synchronized CtClass createClass( diff --git a/src/main/java/io/beanmapper/dynclass/DynamicClassGeneratorHelper.java b/src/main/java/io/beanmapper/dynclass/DynamicClassGeneratorHelper.java deleted file mode 100644 index 8367981f..00000000 --- a/src/main/java/io/beanmapper/dynclass/DynamicClassGeneratorHelper.java +++ /dev/null @@ -1,36 +0,0 @@ -package io.beanmapper.dynclass; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; - -import io.beanmapper.exceptions.BeanNoNeighboursException; -import javassist.CtClass; - -public class DynamicClassGeneratorHelper { - - private DynamicClassGeneratorHelper() { - } - - /** - * Gets a neighbouring {@link Class class} relative to the class represented by the given {@link CtClass}. - * This is done so that it can be passed to the {@link CtClass#toClass(Class)}-method, - * which should be used for compatibility with Java 16+ Reflection. - * @param ctClass - representation of a class. - * @return A neighbouring class relative to the class represented by the CtClass. - */ - public static Class getNeighbourClass(CtClass ctClass) { - try (InputStream inputStream = ClassLoader.getSystemResourceAsStream(ctClass.getPackageName().replaceAll("[.]", "/")); - InputStreamReader inputStreamReader = new InputStreamReader(inputStream); - BufferedReader bufferedReader = new BufferedReader(inputStreamReader)) { - String className = bufferedReader.lines() - .filter(line -> line.endsWith(".class")) - .findFirst() - .orElseThrow(ClassNotFoundException::new); - return Class.forName(ctClass.getPackageName() + "." + className.substring(0, className.lastIndexOf('.'))); - } catch (IOException | ClassNotFoundException | NullPointerException e) { - throw new BeanNoNeighboursException(); - } - } -} diff --git a/src/main/java/io/beanmapper/dynclass/GeneratedClass.java b/src/main/java/io/beanmapper/dynclass/GeneratedClass.java index 57c6d112..d5bca9b4 100644 --- a/src/main/java/io/beanmapper/dynclass/GeneratedClass.java +++ b/src/main/java/io/beanmapper/dynclass/GeneratedClass.java @@ -12,9 +12,9 @@ public class GeneratedClass { public final Class generatedClass; - public GeneratedClass(CtClass ctClass) throws CannotCompileException { + public GeneratedClass(CtClass ctClass, Class baseClass) throws CannotCompileException { this.ctClass = ctClass; - this.generatedClass = ctClass.toClass(DynamicClassGeneratorHelper.getNeighbourClass(ctClass)); + this.generatedClass = ctClass.toClass(baseClass); } } \ No newline at end of file diff --git a/src/test/java/io/beanmapper/dynclass/DynamicClassGeneratorHelperTest.java b/src/test/java/io/beanmapper/dynclass/DynamicClassGeneratorHelperTest.java deleted file mode 100644 index 02b04869..00000000 --- a/src/test/java/io/beanmapper/dynclass/DynamicClassGeneratorHelperTest.java +++ /dev/null @@ -1,37 +0,0 @@ -package io.beanmapper.dynclass; - -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertThrows; - -import io.beanmapper.dynclass.model.Person; -import io.beanmapper.exceptions.BeanNoNeighboursException; -import javassist.ClassPool; -import javassist.CtClass; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; - -class DynamicClassGeneratorHelperTest { - - private ClassPool classPool; - - @BeforeEach - void initClassPool() { - this.classPool = ClassPool.getDefault(); - } - - @Test - void testNoNeighbourFoundDueToNonExistentPackage() { - assertThrows(BeanNoNeighboursException.class, () -> { - CtClass ctClass = classPool.makeClass("io.beanmapper.dynclass.no_neighbours.TestClass"); - DynamicClassGeneratorHelper.getNeighbourClass(ctClass); - }); - } - - @Test - void testPackageOfNeighbourEqualsPackageOfMappedClass() { - CtClass personCtClass = classPool.makeClass("io.beanmapper.dynclass.model.Person"); - Class neighbourClass = DynamicClassGeneratorHelper.getNeighbourClass(personCtClass); - assertEquals(neighbourClass.getPackage(), Person.class.getPackage()); - } -} \ No newline at end of file