[BAEL-5077] Hidden Classes (#11663)
This commit is contained in:
parent
53780ceaf2
commit
fa2b75a81c
|
@ -21,6 +21,11 @@
|
|||
<artifactId>commons-lang3</artifactId>
|
||||
<version>${commons-lang3.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons-io.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
package com.baeldung.hidden.classes;
|
||||
|
||||
public class HiddenClass {
|
||||
public String convertToUpperCase(String s) {
|
||||
return s.toUpperCase();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
package com.baeldung.hidden.classes;
|
||||
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodHandles.Lookup.ClassOption;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.apache.commons.io.IOUtils;
|
||||
import org.junit.jupiter.api.Assertions;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class HiddenClassUnitTest {
|
||||
|
||||
private static final Logger LOG = LoggerFactory.getLogger(HiddenClassUnitTest.class);
|
||||
|
||||
@Test
|
||||
void whenInvokeMethodOnHiddenClass_thenSuccess() {
|
||||
// Initiate lookup class
|
||||
MethodHandles.Lookup lookup = MethodHandles.lookup();
|
||||
|
||||
// Create a byte code of a class
|
||||
|
||||
Class<?> clazz = HiddenClass.class;
|
||||
String className = clazz.getName();
|
||||
String classAsPath = className.replace('.', '/') + ".class";
|
||||
InputStream stream = clazz.getClassLoader()
|
||||
.getResourceAsStream(classAsPath);
|
||||
|
||||
try {
|
||||
// Define hidden class with byte code
|
||||
Class<?> hiddenClass = lookup.defineHiddenClass(IOUtils.toByteArray(stream), true, ClassOption.NESTMATE)
|
||||
.lookupClass();
|
||||
Object hiddenClassObject = hiddenClass.getConstructor()
|
||||
.newInstance();
|
||||
|
||||
Method method = hiddenClassObject.getClass()
|
||||
.getDeclaredMethod("convertToUpperCase", String.class);
|
||||
|
||||
Assertions.assertEquals(true, hiddenClass.isHidden());
|
||||
|
||||
Assertions.assertEquals("HELLO", method.invoke(hiddenClassObject, "Hello"));
|
||||
|
||||
Assertions.assertEquals(this.getClass()
|
||||
.getClassLoader(), hiddenClass.getClassLoader());
|
||||
|
||||
Assertions.assertEquals(null, hiddenClass.getCanonicalName());
|
||||
|
||||
Assertions.assertThrows(ClassNotFoundException.class, () -> Class.forName(hiddenClass.getName()));
|
||||
|
||||
Assertions.assertThrows(ClassNotFoundException.class, () -> lookup.findClass(hiddenClass.getName()));
|
||||
|
||||
} catch (Exception e) {
|
||||
LOG.error("Couldn't instantiate hidden class" + e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue