/*
* Copyright ( c ) 2006 , 2016 , 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
* @ bug 6431735
* @ summary Unexpected ClassCastException in ThreadReference . forceEarlyReturn
* @ author Jim Holmlund
*
* @ run build TestScaffold VMConnection TargetListener TargetAdapter
* @ run compile - g EarlyReturnNegativeTest . java
* @ run driver EarlyReturnNegativeTest
*/
import com.sun.jdi.*;
import com.sun.jdi.event.*;
import com.sun.jdi.request.*;
import java.util.*;
import java.net.URLClassLoader;
import java.net.URL;
import java.lang.reflect.Array;
/*
* This test has a debuggee which calls an instance method
* for each kind of JDI value return type .
*
* The debugger sets breakpoints in all methods . When a breakpoint
* is hit the debugger requests an early return and supplies a new
* return value . The new value is not compatible with the method ' s
* return type so an InvalidTypeException should be thrown .
*
* Each value is stored in a static var in the debuggee . The debugger
* gets the values from these static vars to pass back to the
* debuggee in forceEarlyReturn .
*
* This test was created out of EarlyReturnTest . java . Not all of the
* debuggee methods are actually used , just the ones needed to test
* for correct operation . I left the others in just in case they come
* in handy in the future .
*/
class EarlyReturnNegativeTarg {
/*
* These are the values that will be used by methods
* returning normally .
*/
static URL[] urls = new URL[1 ];
public static byte byteValue = 89 ;
public static char charValue = 'x' ;
public static double doubleValue = 2 .2 ;
public static float floatValue = 3 .3 f;
public static int intValue = 1 ;
public static long longValue = Long .MAX_VALUE;
public static short shortValue = 8 ;
public static boolean booleanValue = false ;
public static Class classValue = Object.class ;
public static ClassLoader classLoaderValue;
{
try {
urls[0 ] = new URL("file:/foo" );
} catch (java.net.MalformedURLException ex) {
throw new AssertionError(ex);
}
classLoaderValue = new URLClassLoader(urls);
}
public static Thread threadValue = Thread .currentThread();
public static ThreadGroup threadGroupValue = threadValue.getThreadGroup();
public static String stringValue = "abc" ;
public static int [] intArrayValue = new int [] {1 , 2 , 3 };
public static Object[] objectArrayValue = new Object[] {"a" , "b" , "c" };
public static EarlyReturnNegativeTarg objectValue =
new EarlyReturnNegativeTarg();
public String ivar = stringValue;
// Used to show which set of tests follows
public static String s_show(String p1) { return p1;}
// These are the instance methods
public byte i_bytef() { return byteValue; }
public char i_charf() { return charValue; }
public double i_doublef() { return doubleValue; }
public float i_floatf() { return floatValue; }
public int i_intf() { return intValue; }
public long i_longf() { return longValue; }
public short i_shortf() { return shortValue; }
public boolean i_booleanf() { return booleanValue; }
public String i_stringf() { return stringValue; }
public Class i_classf() { return classValue; }
public ClassLoader i_classLoaderf()
{ return classLoaderValue; }
public Thread i_threadf() { return threadValue; }
public ThreadGroup i_threadGroupf()
{ return threadGroupValue; }
public int [] i_intArrayf() { return intArrayValue; }
public Object[] i_objectArrayf() { return objectArrayValue; }
public Object i_nullObjectf() { return null ; }
public Object i_objectf() { return objectValue; }
public void i_voidf() {}
static void doit(EarlyReturnNegativeTarg xx) throws Exception {
System.err.print("debugee in doit " );
s_show("========== Testing instance methods ================" );
xx.i_bytef();
xx.i_charf();
xx.i_doublef();
xx.i_floatf();
xx.i_intf();
xx.i_longf();
xx.i_shortf();
xx.i_booleanf();
xx.i_stringf();
xx.i_intArrayf();
xx.i_objectArrayf();
xx.i_classf();
xx.i_classLoaderf();
xx.i_threadf();
xx.i_threadGroupf();
xx.i_nullObjectf();
xx.i_objectf();
xx.i_voidf();
}
public static void main(String[] args) throws Exception {
/*
* The debugger will stop at the start of main ,
* set breakpoints and then do a resume .
*/
System.err.println("debugee in main" );
EarlyReturnNegativeTarg xx =
new EarlyReturnNegativeTarg();
doit(xx);
}
}
public class EarlyReturnNegativeTest extends TestScaffold {
static VirtualMachineManager vmm ;
ClassType targetClass;
Field theValueField;
ByteValue byteVV;
CharValue charVV;
DoubleValue doubleVV;
FloatValue floatVV;
IntegerValue integerVV;
LongValue longVV;
ShortValue shortVV;
BooleanValue booleanVV;
ObjectReference objectVV;
ArrayReference intArrayVV;
ArrayReference objectArrayVV;
VoidValue voidVV;
EarlyReturnNegativeTest(String args[]) {
super (args);
}
public static void main(String[] args) throws Exception {
EarlyReturnNegativeTest meee = new EarlyReturnNegativeTest(args);
vmm = Bootstrap.virtualMachineManager();
meee.startTests();
}
public BreakpointRequest setBreakpoint(String clsName,
String methodName,
String methodSignature) {
ReferenceType rt = findReferenceType(clsName);
if (rt == null ) {
rt = resumeToPrepareOf(clsName).referenceType();
}
Method method = findMethod(rt, methodName, methodSignature);
if (method == null ) {
throw new IllegalArgumentException("Bad method name/signature" );
}
BreakpointRequest bpr = eventRequestManager().createBreakpointRequest(method.location());
bpr.setSuspendPolicy(EventRequest.SUSPEND_ALL);
bpr.enable();
return bpr;
}
void doEarly(ThreadReference tr, String methodName, Value val) {
try {
tr.forceEarlyReturn(val);
} catch (InvalidTypeException ex) {
System.out.println("Ok: " + methodName);
return ;
} catch (Exception ex) {
failure("failure: " + ex.toString());
ex.printStackTrace();
return ;
}
failure("Expected InvalidTypeException for " + methodName + ", " + val + " but didn't get it." );
}
public void breakpointReached(BreakpointEvent event) {
String origMethodName = event.location().method().name();
String methodName = origMethodName.substring(2 );
ThreadReference tr = event.thread ();
if (vm().canForceEarlyReturn()) {
/* There are some incompatible classes of values. In the following,
* we test each combination .
*/
if ("shortf" .equals(methodName)){
doEarly(tr, origMethodName, booleanVV);
doEarly(tr, origMethodName, objectVV);
doEarly(tr, origMethodName, voidVV);
doEarly(tr, origMethodName, intArrayVV);
doEarly(tr, origMethodName, objectArrayVV);
} else if ("booleanf" .equals(methodName)) {
doEarly(tr, origMethodName, shortVV);
doEarly(tr, origMethodName, objectVV);
doEarly(tr, origMethodName, voidVV);
doEarly(tr, origMethodName, intArrayVV);
doEarly(tr, origMethodName, objectArrayVV);
} else if ("intArrayf" .equals(methodName)) {
doEarly(tr, origMethodName, booleanVV);
doEarly(tr, origMethodName, shortVV);
doEarly(tr, origMethodName, voidVV);
doEarly(tr, origMethodName, objectVV);
doEarly(tr, origMethodName, objectArrayVV);
} else if ("objectArrayf" .equals(methodName)) {
doEarly(tr, origMethodName, booleanVV);
doEarly(tr, origMethodName, shortVV);
doEarly(tr, origMethodName, voidVV);
doEarly(tr, origMethodName, objectVV);
doEarly(tr, origMethodName, intArrayVV);
} else if ("objectf" .equals(methodName)) {
doEarly(tr, origMethodName, booleanVV);
doEarly(tr, origMethodName, shortVV);
doEarly(tr, origMethodName, voidVV);
} else if ("voidf" .equals(methodName)) {
doEarly(tr, origMethodName, booleanVV);
doEarly(tr, origMethodName, shortVV);
doEarly(tr, origMethodName, objectVV);
doEarly(tr, origMethodName, intArrayVV);
doEarly(tr, origMethodName, objectArrayVV);
} else {
// just ignore others
System.out.println("Ignoring: " + methodName);
return ;
}
} else {
System.out.println("Cannot force early return for method: " + origMethodName);
}
}
protected void runTests() throws Exception {
/*
* Get to the top of main ( )
* to determine targetClass and mainThread
*/
BreakpointEvent bpe = startToMain("EarlyReturnNegativeTarg" );
targetClass = (ClassType)bpe.location().declaringType();
mainThread = bpe.thread ();
/*
* We set and enable breakpoints on all of the interesting
* methods called by doit ( ) . In the breakpointReached ( )
* handler we force an early return with a different return
* value .
*
*/
setBreakpoint("EarlyReturnNegativeTarg" , "i_bytef" , "()B" );
setBreakpoint("EarlyReturnNegativeTarg" , "i_charf" , "()C" );
setBreakpoint("EarlyReturnNegativeTarg" , "i_doublef" , "()D" );
setBreakpoint("EarlyReturnNegativeTarg" , "i_floatf" , "()F" );
setBreakpoint("EarlyReturnNegativeTarg" , "i_intf" , "()I" );
setBreakpoint("EarlyReturnNegativeTarg" , "i_longf" , "()J" );
setBreakpoint("EarlyReturnNegativeTarg" , "i_shortf" , "()S" );
setBreakpoint("EarlyReturnNegativeTarg" , "i_booleanf" , "()Z" );
setBreakpoint("EarlyReturnNegativeTarg" , "i_stringf" , "()Ljava/lang/String;" );
setBreakpoint("EarlyReturnNegativeTarg" , "i_intArrayf" , "()[I" );
setBreakpoint("EarlyReturnNegativeTarg" , "i_objectArrayf" , "()[Ljava/lang/Object;" );
setBreakpoint("EarlyReturnNegativeTarg" , "i_classf" , "()Ljava/lang/Class;" );
setBreakpoint("EarlyReturnNegativeTarg" , "i_classLoaderf" , "()Ljava/lang/ClassLoader;" );
setBreakpoint("EarlyReturnNegativeTarg" , "i_threadf" , "()Ljava/lang/Thread;" );
setBreakpoint("EarlyReturnNegativeTarg" , "i_threadGroupf" , "()Ljava/lang/ThreadGroup;" );
setBreakpoint("EarlyReturnNegativeTarg" , "i_nullObjectf" , "()Ljava/lang/Object;" );
setBreakpoint("EarlyReturnNegativeTarg" , "i_objectf" , "()Ljava/lang/Object;" );
setBreakpoint("EarlyReturnNegativeTarg" , "i_voidf" , "()V" );
/* Create Value objects to be passed in forceEarlyReturn calls */
Field theValueField = targetClass.fieldByName("byteValue" );
byteVV = (ByteValue)targetClass.getValue(theValueField);
theValueField = targetClass.fieldByName("charValue" );
charVV = (CharValue)targetClass.getValue(theValueField);
theValueField = targetClass.fieldByName("doubleValue" );
doubleVV = (DoubleValue)targetClass.getValue(theValueField);
theValueField = targetClass.fieldByName("floatValue" );
floatVV = (FloatValue)targetClass.getValue(theValueField);
theValueField = targetClass.fieldByName("intValue" );
integerVV = (IntegerValue)targetClass.getValue(theValueField);
theValueField = targetClass.fieldByName("longValue" );
longVV = (LongValue)targetClass.getValue(theValueField);
theValueField = targetClass.fieldByName("shortValue" );
shortVV = (ShortValue)targetClass.getValue(theValueField);
theValueField = targetClass.fieldByName("booleanValue" );
booleanVV = (BooleanValue)targetClass.getValue(theValueField);
theValueField = targetClass.fieldByName("objectValue" );
objectVV = (ObjectReference)targetClass.getValue(theValueField);
theValueField = targetClass.fieldByName("intArrayValue" );
intArrayVV = (ArrayReference)targetClass.getValue(theValueField);
theValueField = targetClass.fieldByName("objectArrayValue" );
objectArrayVV = (ArrayReference)targetClass.getValue(theValueField);
voidVV = vm().mirrorOfVoid();
/* Here we go. This adds 'this' as a listener so
* that our handlers above will be called .
*/
listenUntilVMDisconnect();
if (!testFailed) {
System.out.println();
System.out.println("EarlyReturnNegativeTest: passed" );
} else {
System.out.println();
System.out.println("EarlyReturnNegativeTest: failed" );
throw new Exception("EarlyReturnNegativeTest: failed" );
}
}
}
Messung V0.5 in Prozent C=97 H=90 G=93
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland