Quelle Reflection.java
Sprache: JAVA
/*
* Copyright ( c ) 2020 , 2022 , Oracle and / or its affiliates . All rights reserved .
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER .
*
* This code is free software ; you can redistribute it and / or modify it
* under the terms of the GNU General Public License version 2 only , as
* published by the Free Software Foundation .
*
* This code is distributed in the hope that it will be useful , but WITHOUT
* ANY WARRANTY ; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE . See the GNU General Public License
* version 2 for more details ( a copy is included in the LICENSE file that
* accompanied this code ) .
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work ; if not , write to the Free Software Foundation ,
* Inc . , 51 Franklin St , Fifth Floor , Boston , MA 02110 - 1301 USA .
*
* Please contact Oracle , 500 Oracle Parkway , Redwood Shores , CA 94065 USA
* or visit www . oracle . com if you need additional information or have any
* questions .
*/
/**
* @ test
* @ summary Test virtual threads using core reflection
* @ modules java . base / java . lang : + open
* @ library / test / lib
* @ enablePreview
* @ run testng Reflection
*/
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.locks.LockSupport;
import jdk.test.lib.thread .VThreadRunner;
import org.testng.SkipException;
import org.testng.annotations.Test;
import static org.testng.Assert .*;
public class Reflection {
/**
* Test invoking static method .
*/
@Test
public void testInvokeStatic1() throws Exception {
VThreadRunner.run(() -> {
int result = (int ) divideMethod().invoke(null , 20 , 2 );
assertTrue(result == 10 );
});
}
/**
* Test that InvocationTargetException is thrown when a static method throws
* exception .
*/
@Test
public void testInvokeStatic2() throws Exception {
VThreadRunner.run(() -> {
try {
divideMethod().invoke(null , 20 , 0 );
fail();
} catch (InvocationTargetException e) {
assertTrue(e.getCause() instanceof ArithmeticException);
}
});
}
/**
* Test that IllegalArgumentException is thrown when trying to invoke a static
* method with bad parameters .
*/
@Test
public void testInvokeStatic3() throws Exception {
VThreadRunner.run(() -> {
assertThrows(IllegalArgumentException.class ,
() -> divideMethod().invoke(null ));
assertThrows(IllegalArgumentException.class ,
() -> divideMethod().invoke(null , 1 ));
assertThrows(IllegalArgumentException.class ,
() -> divideMethod().invoke(null , 1 , 2 , 3 ));
assertThrows(IllegalArgumentException.class ,
() -> divideMethod().invoke(new Object()));
assertThrows(IllegalArgumentException.class ,
() -> divideMethod().invoke(new Object(), 1 ));
assertThrows(IllegalArgumentException.class ,
() -> divideMethod().invoke(new Object(), 1 , 2 , 3 ));
});
}
/**
* Test that ExceptionInInitializerError is thrown when invoking a static
* method triggers its class to be initialized and it fails with exception .
*/
@Test
public void testInvokeStatic4() throws Exception {
VThreadRunner.run(() -> {
Method foo = BadClass1.class .getDeclaredMethod("foo" );
try {
foo.invoke(null );
fail();
} catch (ExceptionInInitializerError e) {
assertTrue(e.getCause() instanceof ArithmeticException);
}
});
}
static class BadClass1 {
static {
if (1 ==1 ) throw new ArithmeticException();
}
static void foo() { }
}
/**
* Test that an error is thrown when invoking a static method triggers its
* class to be initialized and it fails with an error .
*/
@Test
public void testInvokeStatic5() throws Exception {
VThreadRunner.run(() -> {
Method foo = BadClass2.class .getDeclaredMethod("foo" );
assertThrows(AbstractMethodError.class , () -> foo.invoke(null ));
});
}
static class BadClass2 {
static {
if (1 ==1 ) throw new AbstractMethodError();
}
static void foo() { }
}
/**
* Test that invoking a static method does not pin the carrier thread .
*/
@Test
public void testInvokeStatic6() throws Exception {
if (!ThreadBuilders.supportsCustomScheduler())
throw new SkipException("No support for custom schedulers" );
Method parkMethod = Parker.class .getDeclaredMethod("park" );
try (ExecutorService scheduler = Executors.newFixedThreadPool(1 )) {
Thread .Builder builder = ThreadBuilders.virtualThreadBuilder(scheduler);
ThreadFactory factory = builder.factory();
Thread vthread = factory.newThread(() -> {
try {
parkMethod.invoke(null ); // blocks
} catch (Exception e) { }
});
vthread.start();
try {
// give thread time to be scheduled
Thread .sleep(100 );
// unpark with another virtual thread, runs on same carrier thread
Thread unparker = factory.newThread(() -> LockSupport.unpark(vthread));
unparker.start();
unparker.join();
} finally {
LockSupport.unpark(vthread); // in case test fails
}
}
}
/**
* Test invoking instance method .
*/
@Test
public void testInvokeInstance1() throws Exception {
VThreadRunner.run(() -> {
var adder = new Adder();
Adder.addMethod().invoke(adder, 5 );
assertTrue(adder.sum == 5 );
});
}
/**
* Test that InvocationTargetException is thrown when an instance method throws
* exception .
*/
@Test
public void testInvokeInstance2() throws Exception {
VThreadRunner.run(() -> {
var adder = new Adder();
try {
Adder.addMethod().invoke(adder, -5 );
fail();
} catch (InvocationTargetException e) {
assertTrue(e.getCause() instanceof IllegalArgumentException);
}
});
}
/**
* Test that NullPointerException and IllegalArgumentException are thrown when
* trying to invoke an instance method with null or bad parameters .
*/
@Test
public void testInvokeInstance3() throws Exception {
VThreadRunner.run(() -> {
var adder = new Adder();
Method addMethod = Adder.addMethod();
assertThrows(NullPointerException.class ,
() -> addMethod.invoke(null ));
assertThrows(IllegalArgumentException.class ,
() -> addMethod.invoke(adder));
assertThrows(IllegalArgumentException.class ,
() -> addMethod.invoke(adder, 1 , 2 ));
assertThrows(IllegalArgumentException.class ,
() -> addMethod.invoke(adder, 1 , "hi" ));
assertThrows(IllegalArgumentException.class ,
() -> addMethod.invoke(adder, "hi" ));
});
}
/**
* Test invoking newInstance to create an object .
*/
@Test
public void testNewInstance1() throws Exception {
VThreadRunner.run(() -> {
Constructor<?> ctor = Adder.class .getDeclaredConstructor(long .class );
Adder adder = (Adder) ctor.newInstance(10 );
assertTrue(adder.sum == 10 );
});
}
/**
* Test that InvocationTargetException is thrown when a constructor throws
* exception .
*/
@Test
public void testNewInstance2() throws Exception {
VThreadRunner.run(() -> {
Constructor<?> ctor = Adder.class .getDeclaredConstructor(long .class );
try {
ctor.newInstance(-10 );
fail();
} catch (InvocationTargetException e) {
assertTrue(e.getCause() instanceof IllegalArgumentException);
}
});
}
/**
* Test that IllegalArgumentException is thrown when newInstacne is called
* with bad parameters .
*/
@Test
public void testNewInstance3() throws Exception {
VThreadRunner.run(() -> {
var adder = new Adder();
Constructor<?> ctor = Adder.class .getDeclaredConstructor(long .class );
assertThrows(IllegalArgumentException.class ,
() -> ctor.newInstance((Object[])null ));
assertThrows(IllegalArgumentException.class ,
() -> ctor.newInstance(adder));
assertThrows(IllegalArgumentException.class ,
() -> ctor.newInstance(adder, null ));
assertThrows(IllegalArgumentException.class ,
() -> ctor.newInstance(adder, "foo" ));
assertThrows(IllegalArgumentException.class ,
() -> ctor.newInstance(adder, 1 , 2 ));
});
}
/**
* Test that ExceptionInInitializerError is thrown when invoking newInstance
* triggers the class to be initialized and it fails with exception .
*/
@Test
public void testNewInstance4() throws Exception {
VThreadRunner.run(() -> {
Constructor<?> ctor = BadClass3.class .getDeclaredConstructor();
try {
ctor.newInstance((Object[])null );
fail();
} catch (ExceptionInInitializerError e) {
assertTrue(e.getCause() instanceof ArithmeticException);
}
});
}
static class BadClass3 {
static {
if (1 ==1 ) throw new ArithmeticException();
}
static void foo() { }
}
/**
* Test that error is thrown when invoking newInstance triggers the class
* to be initialized and it fails with an error .
*/
@Test
public void testNewInstance5() throws Exception {
VThreadRunner.run(() -> {
Constructor<?> ctor = BadClass4.class .getDeclaredConstructor();
assertThrows(AbstractMethodError.class , () -> ctor.newInstance((Object[])null ));
});
}
static class BadClass4 {
static {
if (1 ==1 ) throw new AbstractMethodError();
}
static void foo() { }
}
/**
* Test that newInstance does not pin the carrier thread
*/
@Test
public void testNewInstance6() throws Exception {
if (!ThreadBuilders.supportsCustomScheduler())
throw new SkipException("No support for custom schedulers" );
Constructor<?> ctor = Parker.class .getDeclaredConstructor();
try (ExecutorService scheduler = Executors.newFixedThreadPool(1 )) {
Thread .Builder builder = ThreadBuilders.virtualThreadBuilder(scheduler);
ThreadFactory factory = builder.factory();
Thread vthread = factory.newThread(() -> {
try {
ctor.newInstance();
} catch (Exception e) { }
});
vthread.start();
Thread .sleep(100 ); // give thread time to be scheduled
// unpark with another virtual thread, runs on same carrier thread
factory.newThread(() -> LockSupport.unpark(vthread)).start();
}
}
// -- support classes and methods --
static int divide(int x, int y) {
return x / y;
}
static Method divideMethod() throws NoSuchMethodException {
return Reflection.class .getDeclaredMethod("divide" , int .class , int .class );
}
static class Adder {
long sum;
Adder() { }
Adder(long x) {
if (x < 0 )
throw new IllegalArgumentException();
sum = x;
}
Adder add(long x) {
if (x < 0 )
throw new IllegalArgumentException();
sum += x;
return this ;
}
static Method addMethod() throws NoSuchMethodException {
return Adder.class .getDeclaredMethod("add" , long .class );
}
long sum() {
return sum;
}
}
static class Parker {
Parker() {
LockSupport.park();
}
static void park() {
LockSupport.park();
}
}
}
Messung V0.5 in Prozent C=94 H=78 G=86
¤ Dauer der Verarbeitung: 0.11 Sekunden
(vorverarbeitet am 2026-10-11)
¤
*© Formatika GbR, Deutschland
2026-10-11
Neuigkeiten
Aktuelles
Motto des Tages
Open Source Software
Jenseits des Üblichen ....
Besucherstatistik
Statistik
#Sources=1127926
#Domains=2039723