Reflection project. A similar project is working on Maven. As soon as I transfer to Gradle, it throws a LinkageError in the line:
Class<Main> clazz = Main.class;
Error code:
Exception in thread "main" java.lang.LinkageError: loader constraint violation: loader 'app' wants to load class org.geekhub.studentsregistry.students.Main. A different class with the same name was previously loaded by com.sun.tools.javac.launcher.Main$MemoryClassLoader @7494f96a. (org.geekhub.studentsregistry.students.Mainis in unnamed module of loader com.sun.tools.javac.launcher.Main$MemoryClassLoader @7494f96a, parent loader 'app')
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1016)
at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:151)
at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:825)
at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:723)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:646)
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:604)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:168)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
at org.geekhub.studentsregistry.students.MainCreator.getConstructorFromMain(MainCreator.java:49)
at org.geekhub.studentsregistry.students.MainCreator.create(MainCreator.java:32)
at org.geekhub.studentsregistry.students.Main.main(Main.java:60)
Main creator code:
public class MainCreator {
Main create() {
try {
return (Main) getNewInstanceByReflection(
getClassesWithDependencyAnnotation(),
getConstructorFromMainClass());
} catch (IllegalAccessException | InvocationTargetException | InstantiationException | ClassNotFoundException | NoSuchMethodException e) {
e.printStackTrace();
}
return null;
}
private Object getNewInstance()
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<Main> clazz = Main.class;
Constructor<?> constructor = clazz.getDeclaredConstructors()[0];
Class<?>[] params = constructor.getParameterTypes();
Object[] args = new Object[constructor.getParameterCount()];
for (int i = 0; i < args.length; i++) {
args[i] = params[i].getDeclaredConstructor().newInstance();
}
return clazz.getDeclaredConstructors()[0].newInstance(args);
}
private List<Class<?>> getClassesWithDependencyAnnotation() {
Reflections reflections = new Reflections(new ConfigurationBuilder()
.setUrls(ClasspathHelper.forPackage("."))
.setScanners(new TypeAnnotationsScanner(), new SubTypesScanner()));
return new ArrayList<>(reflections.getTypesAnnotatedWith(Dependency.class));
}
private Constructor<?> getConstructorFromMainClass() throws ClassNotFoundException {
Class<?> mainClass = Main.class;
Constructor<?>[] constructors = mainClass.getDeclaredConstructors();
return constructors[0];
}
private Object getNewInstanceByReflection(List<Class<?>> classesForNewInstance, Constructor<?> constructorByClassLoader)
throws ClassNotFoundException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchMethodException {
int count = constructorByClassLoader.getParameterCount();
List<String> classes = classesForNewInstance.stream().map(Class::getName).collect(Collectors.toList());
Class<?>[] constructorParameterTypes = constructorByClassLoader.getParameterTypes();
Object[] argumentsListForNewInstance1 = new Object[count];
String paramName;
for (int i = 0; i < count; i++) {
paramName = constructorParameterTypes[i].getName();
if (!classes.contains(paramName)) {
throw new ClassNotFoundException("Not found input class to create Main: "
+ constructorParameterTypes[i].getSimpleName());
} else {
argumentsListForNewInstance1[i] = constructorParameterTypes[i].getDeclaredConstructor().newInstance();
}
}
Constructor<?> constructorDefault = Main.class.getDeclaredConstructors()[0];
return constructorDefault.newInstance(argumentsListForNewInstance1);
}
Main code:
public class Main {
private final ClassA a;
private final ClassB b;
private final ClassC c;
public Main(ClassA a, ClassB b, ClassC c) {
this.a = a;
this.b = b;
this.c = c;
}
public static void main(String[] args) {
MainCreator mainCreator = new MainCreator();
Main main = mainCreator.create();
main.run();
}
private void run(){
System.out.println("Run");
System.out.println("a = " + a.getClass());
System.out.println("b = " + b.getClass());
System.out.println("c = " + c.getClass());
}
}
builde.cradle:
plugins {
id 'java'
id 'application'
}
group = 'org.geekhub'
version '1.0-SNAPSHOT'
sourceCompatibility = JavaVersion.VERSION_15
application {
mainClassName = './src/main/java/org/geekhub/studentsregistry/students/Main.java'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.testng:testng:6.14.3'
implementation 'org.testng:testng:6.14.3'
implementation group: 'org.reflections', name: 'reflections', version: '0.9.11'
testCompile group: 'org.testng', name: 'testng', version: '7.3.0'
testCompile group: 'org.mockito', name: 'mockito-core', version: '3.6.28'
testImplementation group: 'org.assertj', name: 'assertj-core', version: '3.19.0'
implementation project(':Homework:console-app')
implementation project(':Homework:rules')
}
run {
args = ['5', 'AUTO']
standardInput = System.in
}
test {
useTestNG()
}
compileJava {
options.compilerArgs += ['--enable-preview']
}
compileTestJava {
options.compilerArgs += ['--enable-preview']
}
tasks.withType(JavaExec) {
jvmArgs += '--enable-preview'
jvmArgs += '--source 15'
}
tasks.withType(Test) {
jvmArgs += '--enable-preview'
}
I`v tried different ClassLoaders, nothing helps.
Please, help. What I have to do?