undefect. CWE-407 — 63 sites patched across 27 ecosystems
Authors: russell@unturf.com · brackishbert@gmail.com · foxhop.net · TimeHexOn.com Patches, unit tests, benchmarks, whitepaper, and outreach briefs. Public domain — no copyright claimed. Use freely.
This commit is contained in:
commit
0a580b313d
70422 changed files with 17213626 additions and 0 deletions
159
test/jdk/java/rmi/server/ObjID/randomIDs/RandomIDs.java
Normal file
159
test/jdk/java/rmi/server/ObjID/randomIDs/RandomIDs.java
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
/*
|
||||
* Copyright (c) 2006, 2012, 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 6364692
|
||||
* @summary When the "java.rmi.server.randomIDs" system property is
|
||||
* not defined, the ObjID() constructor should behave as if it were
|
||||
* set to "true" and generate random object numbers; if the property
|
||||
* is defined to something other than "true" (ignoring case), then
|
||||
* ObjID() should still generate sequential object numbers.
|
||||
* @author Peter Jones
|
||||
*
|
||||
* @run main/othervm RandomIDs random
|
||||
* @run main/othervm -Djava.rmi.server.randomIDs=true RandomIDs random
|
||||
* @run main/othervm -Djava.rmi.server.randomIDs=false RandomIDs sequential
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.rmi.server.ObjID;
|
||||
|
||||
public class RandomIDs {
|
||||
private static final int COUNT = 10000;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
boolean shouldBeRandom = false;
|
||||
boolean shouldBeSequential = false;
|
||||
|
||||
String usage = "Usage: java RandomIDs [random|sequential]";
|
||||
if (args.length != 1) {
|
||||
System.err.println(usage);
|
||||
throw new Error("wrong number of arguments");
|
||||
} else if (args[0].equals("random")) {
|
||||
shouldBeRandom = true;
|
||||
} else if (args[0].equals("sequential")) {
|
||||
shouldBeSequential = true;
|
||||
} else {
|
||||
System.err.println(usage);
|
||||
throw new Error("invalid argument");
|
||||
}
|
||||
|
||||
System.err.println("\nRegression test for bug 6364692\n");
|
||||
String propertyValue = System.getProperty("java.rmi.server.randomIDs");
|
||||
System.err.println(
|
||||
"Value of java.rmi.server.randomIDs system property: " +
|
||||
(propertyValue != null ? "\"" + propertyValue + "\"" : null));
|
||||
System.err.println(
|
||||
"Expecting object numbers of unique ObjIDs to be: " + args[0]);
|
||||
|
||||
/*
|
||||
* Get the 64-bit "object number" component of COUNT number of
|
||||
* unique (not "well-known") ObjID instances created in
|
||||
* sequence, by writing each to a dummy ObjectOutputStream and
|
||||
* trapping the first writeLong invocation on the stream.
|
||||
*/
|
||||
final long[] objnums = new long[COUNT];
|
||||
for (int i = 0; i < COUNT; i++) {
|
||||
final int j = i;
|
||||
class Escape extends RuntimeException { }
|
||||
try {
|
||||
new ObjID().write(new ObjectOutputStream(new OutputStream() {
|
||||
public void write(int b) { }
|
||||
}) {
|
||||
public void writeLong(long val) throws IOException {
|
||||
objnums[j] = val;
|
||||
throw new Escape();
|
||||
}
|
||||
});
|
||||
throw new Error("writeLong not invoked");
|
||||
} catch (Escape e) {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the object numbers should be random, then verify that
|
||||
* they are. (This verification is certainly not a thorough
|
||||
* evaluation of randomness, but it performs a couple of
|
||||
* simple checks to catch mistakes in ObjID's application of a
|
||||
* CSPRNG: are roughly half the bits set, and can the sequence
|
||||
* be used to get a rough Monte Carlo estimate of pi. Errors
|
||||
* up to 5% are tolerated for both checks.)
|
||||
*/
|
||||
if (shouldBeRandom) {
|
||||
int bitCount = 0;
|
||||
int piHitCount = 0;
|
||||
for (int i = 0; i < COUNT; i++) {
|
||||
bitCount += Long.bitCount(objnums[i]);
|
||||
double x = ((double) (objnums[i] >>> 32)) / (1L << 32);
|
||||
double y = ((double) (objnums[i] & 0xFFFFFFFFL)) / (1L << 32);
|
||||
if (((x * x) + (y * y)) <= 1.0) {
|
||||
piHitCount++;
|
||||
}
|
||||
}
|
||||
|
||||
int bitCountTarget = COUNT * 32;
|
||||
double bitCountError =
|
||||
((double) (bitCount - bitCountTarget)) / bitCountTarget;
|
||||
if (Math.abs(bitCountError) > 0.05) { // tolerate 5% error
|
||||
throw new Error("TEST FAILED: " +
|
||||
"bitCount == " + bitCount);
|
||||
}
|
||||
|
||||
double piEstimate = ((double) piHitCount / COUNT) * 4.0;
|
||||
double piEstimateError = (piEstimate - Math.PI) / Math.PI;
|
||||
if (Math.abs(piEstimateError) > 0.05) { // tolerate 5% error
|
||||
throw new Error("TEST FAILED: " +
|
||||
"piEstimate == " + piEstimate);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If the object numbers should be sequential, then verify
|
||||
* that they are.
|
||||
*/
|
||||
if (shouldBeSequential) {
|
||||
long first = objnums[0];
|
||||
/*
|
||||
* This test currently verifies that the first object
|
||||
* number is zero, but that could be false if one or more
|
||||
* remote objects get exported as part of VM startup-- if
|
||||
* that starts happening, this check could be relaxed.
|
||||
*/
|
||||
if (first != 0) {
|
||||
throw new Error("TEST FAILED: " +
|
||||
"first object number == " + first +
|
||||
" (not zero)");
|
||||
}
|
||||
for (int i = 1; i < COUNT; i++) {
|
||||
if (objnums[i] != first + i) {
|
||||
throw new Error("TEST FAILED: first == " + first + ", " +
|
||||
"objnums[" + i + "] == " + objnums[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
System.err.println("TEST PASSED");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2024, 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 4112682
|
||||
* @summary RMIClassLoader's loadClass() method that takes explicit URLs
|
||||
* should load classes from a class loader that delegates to the current
|
||||
* thread's context class loader (not just the base class loader always).
|
||||
* @author Peter Jones
|
||||
*
|
||||
* @library ../../../testlibrary
|
||||
* @modules java.rmi/sun.rmi.registry
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary Dummy
|
||||
* @run main/othervm/timeout=120 DelegateToContextLoader
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.security.*;
|
||||
import java.rmi.server.RMIClassLoader;
|
||||
|
||||
public class DelegateToContextLoader {
|
||||
|
||||
/** name of target class to attempt to load */
|
||||
private static final String className = "Dummy";
|
||||
|
||||
/** name of file containing definition for target class */
|
||||
private static final String classFileName = className + ".class";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
URL codebaseURL = TestLibrary.
|
||||
installClassInCodebase(className, "codebase");
|
||||
|
||||
/* Create a URLClassLoader to load from the codebase and set it
|
||||
* as this thread's context class loader. We do not use the
|
||||
* URLClassLoader.newInstance() method so that the test will
|
||||
* compile with more early versions of the JDK.
|
||||
*
|
||||
* We can get away with creating a class loader like this
|
||||
* because there is no security manager set yet.
|
||||
*/
|
||||
ClassLoader codebaseLoader =
|
||||
new URLClassLoader(new URL[] { codebaseURL } );
|
||||
Thread.currentThread().setContextClassLoader(codebaseLoader);
|
||||
|
||||
File srcDir = new File(TestLibrary.getProperty("test.classes", "."));
|
||||
|
||||
URL dummyURL = new URL("file", "",
|
||||
srcDir.getAbsolutePath().replace(File.separatorChar, '/') +
|
||||
"/x-files/");
|
||||
|
||||
try {
|
||||
/*
|
||||
* Attempt to load the target class from the dummy URL;
|
||||
* it should be found in the context class loader.
|
||||
*/
|
||||
Class cl = RMIClassLoader.loadClass(dummyURL, className);
|
||||
System.err.println("TEST PASSED: loaded class: " + cl);
|
||||
} catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: target class in context class loader " +
|
||||
"not found using RMIClassLoader");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 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.
|
||||
*/
|
||||
|
||||
public class Dummy {
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2012, 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 4518927
|
||||
* @summary RMIClassLoader.getClassAnnotation() needs to specify behavior
|
||||
* for null class
|
||||
* @author Ann Wollrath
|
||||
*
|
||||
* @library ../../../testlibrary
|
||||
* @modules java.rmi/sun.rmi.registry
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary
|
||||
* @run main/othervm NullClass
|
||||
*/
|
||||
|
||||
import java.rmi.server.RMIClassLoader;
|
||||
|
||||
public class NullClass {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
System.err.println("\nRegression test for bug 4518927\n");
|
||||
|
||||
try {
|
||||
System.err.println("getting class annotation for null class...");
|
||||
String annotation = RMIClassLoader.getClassAnnotation(null);
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: NullPointerException not caught!");
|
||||
} catch (NullPointerException e) {
|
||||
System.err.println("TEST PASSED: NullPointerException caught");
|
||||
} catch (Exception e) {
|
||||
TestLibrary.bomb(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.rmi.MarshalledObject;
|
||||
|
||||
public class FnnClass implements FnnUnmarshal {
|
||||
public Object unmarshal(MarshalledObject mobj)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
return mobj.get();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.rmi.MarshalledObject;
|
||||
|
||||
public interface FnnUnmarshal {
|
||||
Object unmarshal(MarshalledObject mobj)
|
||||
throws IOException, ClassNotFoundException;
|
||||
}
|
||||
|
|
@ -0,0 +1,415 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2024, 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 8280642
|
||||
* @summary functional test for RMIClassLoader.loadProxyClass; test
|
||||
* ensures that the default RMI class loader provider implements
|
||||
* RMIClassLoader.loadProxyClass correctly.
|
||||
*
|
||||
* @author Laird Dornin
|
||||
*
|
||||
* @library ../../../testlibrary
|
||||
* @modules java.rmi/sun.rmi.registry
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary FnnClass FnnUnmarshal NonpublicInterface
|
||||
* NonpublicInterface1 PublicInterface PublicInterface1
|
||||
* @run main/othervm
|
||||
* -Djava.rmi.server.useCodebaseOnly=false LoadProxyClasses
|
||||
*/
|
||||
|
||||
import java.rmi.server.RMIClassLoader;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.rmi.MarshalledObject;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.io.Serializable;
|
||||
import java.io.InvalidClassException;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.zip.Checksum;
|
||||
|
||||
/**
|
||||
* Invokes RMIClassLoader.loadProxyClass() to load a proxy class with
|
||||
* multiple interfaces using RMI class unmarshalling. Test is
|
||||
* composed of cases which each unmarshal a proxy class in a
|
||||
* different environment. All of the cases create needed class
|
||||
* loaders, load appropriate interfaces, create a proxy class that
|
||||
* implements those interfaces, create a marshalled object from that
|
||||
* proxy class, and finally call .get() on that object. Get of the
|
||||
* object should pass in some cases and fail in others.
|
||||
*
|
||||
* 1. Nonpublic interface loaded from the parent of the First
|
||||
* Non-Null class Loader on the execution stack (FNNL). Public
|
||||
* interface loaded from grandparent of FNNL parent. Proxy class must
|
||||
* be defined in non-null FNNL parent. Should succeed.
|
||||
*
|
||||
* 2. Nonpublic interface (java.util.zip.ZipConstants) and public
|
||||
* interface (java.util.zip.CheckSum) loaded from bootclasspath,
|
||||
* proxy class defined in null/boot class loader. Should succeed.
|
||||
*
|
||||
* 3. Disabled. Public interface classes loaded in FNNL are also available in
|
||||
* RMI loader parent. FNNL is grandparent of RMI loader. Proxy class
|
||||
* must be defined in RMI class loader. Should succeed. public
|
||||
* interface must be defined in FNNL. Disabled because the default
|
||||
* RMIClassLoader provider no longer creates class loaders.
|
||||
*
|
||||
* 4. Non-public interfaces have multiple class loaders. Should fail
|
||||
* with a LinkageError.
|
||||
*
|
||||
* 5. Disabled. Interface classes loaded from RMI class loader. Proxy class
|
||||
* defined in RMI class loader. Disabled because the default RMIClassLoader
|
||||
* provider no longer creates class loaders.
|
||||
*
|
||||
* 6. Not all interfaces classes can be loaded from a single class
|
||||
* loader; should fail with ClassNotFoundException. All interface
|
||||
* classes will exist (but not all interfaces will be available from
|
||||
* one class loader).
|
||||
*
|
||||
* 7. prove that proxy loader has correct annotation.
|
||||
*
|
||||
* 8. REMIND: may want to add a case where the FNNL is null (This
|
||||
* would be for class unmarshalling in the implemntation of a remote
|
||||
* method invocation).
|
||||
*/
|
||||
public class LoadProxyClasses {
|
||||
|
||||
private static URL publicUrl = null;
|
||||
|
||||
public static boolean boomerangSemantics = false;
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
System.err.println("\nFunctional test to verify that RMI " +
|
||||
"loads proxy classes correctly\n");
|
||||
|
||||
/* install proxy interfaces */
|
||||
publicUrl =
|
||||
TestLibrary.installClassInCodebase("PublicInterface",
|
||||
"public");
|
||||
URL publicUrl1 =
|
||||
TestLibrary.installClassInCodebase("PublicInterface1",
|
||||
"public1");
|
||||
URL nonpublicUrl =
|
||||
TestLibrary.installClassInCodebase("NonpublicInterface",
|
||||
"nonpublic", false);
|
||||
URL nonpublicUrl1 =
|
||||
TestLibrary.installClassInCodebase("NonpublicInterface1",
|
||||
"nonpublic1", false);
|
||||
URL bothNonpublicUrl =
|
||||
TestLibrary.installClassInCodebase("NonpublicInterface",
|
||||
"bothNonpublic");
|
||||
TestLibrary.installClassInCodebase("NonpublicInterface1",
|
||||
"bothNonpublic");
|
||||
URL fnnUrl =
|
||||
TestLibrary.installClassInCodebase("FnnClass", "fnn");
|
||||
|
||||
/* Case 1 */
|
||||
ClassLoader grandParentPublic =
|
||||
new URLClassLoader(new URL[] {publicUrl});
|
||||
ClassLoader parentNonpublic =
|
||||
new URLClassLoader(new URL[] {nonpublicUrl},
|
||||
grandParentPublic);
|
||||
URLClassLoader fnnLoader1 =
|
||||
new URLClassLoader(new URL[] {fnnUrl}, parentNonpublic);
|
||||
|
||||
Class nonpublicInterface =
|
||||
fnnLoader1.loadClass("NonpublicInterface");
|
||||
Class publicInterface =
|
||||
fnnLoader1.loadClass("PublicInterface");
|
||||
|
||||
Proxy proxy1 = (Proxy) Proxy.newProxyInstance(parentNonpublic,
|
||||
new Class[] {nonpublicInterface, publicInterface},
|
||||
new TestInvocationHandler());
|
||||
unmarshalProxyClass(proxy1, fnnLoader1, parentNonpublic, 1, null);
|
||||
|
||||
|
||||
|
||||
/* Case 2 */
|
||||
Class zipConstantsClass =
|
||||
Class.forName("java.util.zip.ZipConstants");
|
||||
URLClassLoader fnnLoader2 =
|
||||
new URLClassLoader(new URL[] {fnnUrl});
|
||||
Proxy proxy2 = (Proxy) Proxy.newProxyInstance(null,
|
||||
new Class[] {zipConstantsClass, Checksum.class},
|
||||
new TestInvocationHandler());
|
||||
unmarshalProxyClass(proxy2, fnnLoader2,
|
||||
(ClassLoader) null, 2, null);
|
||||
|
||||
|
||||
|
||||
/* Case 3 */
|
||||
Thread currentThread = Thread.currentThread();
|
||||
ClassLoader fnnLoader3 = new URLClassLoader(
|
||||
new URL[] {publicUrl, fnnUrl});
|
||||
ClassLoader newCtxLoader =
|
||||
new URLClassLoader(new URL[] {publicUrl}, fnnLoader3);
|
||||
Class publicInterface3 =
|
||||
fnnLoader3.loadClass("PublicInterface");
|
||||
ClassLoader currentCtxLoader =
|
||||
currentThread.getContextClassLoader();
|
||||
currentThread.setContextClassLoader(newCtxLoader);
|
||||
|
||||
Proxy proxy3 = (Proxy) Proxy.newProxyInstance(newCtxLoader,
|
||||
new Class[] {publicInterface3},
|
||||
new TestInvocationHandler());
|
||||
|
||||
// unmarshalProxyClass(proxy3, fnnLoader3, fnnLoader3,
|
||||
// 3, new Case3Checker());
|
||||
|
||||
currentThread.setContextClassLoader(currentCtxLoader);
|
||||
|
||||
|
||||
|
||||
/* Case 4 */
|
||||
ClassLoader bothNonpublicLoader =
|
||||
new URLClassLoader(new URL[] {bothNonpublicUrl});
|
||||
Class nonpublicInterface4a =
|
||||
bothNonpublicLoader.loadClass("NonpublicInterface");
|
||||
Class nonpublicInterface4b =
|
||||
bothNonpublicLoader.loadClass("NonpublicInterface1");
|
||||
Proxy proxy4 = (Proxy) Proxy.newProxyInstance(bothNonpublicLoader,
|
||||
new Class[] {nonpublicInterface4a, nonpublicInterface4b},
|
||||
new TestInvocationHandler());
|
||||
|
||||
ClassLoader nonpublicLoaderA =
|
||||
new URLClassLoader(new URL[] {nonpublicUrl});
|
||||
ClassLoader nonpublicLoaderB =
|
||||
new URLClassLoader(new URL[] {nonpublicUrl1}, nonpublicLoaderA);
|
||||
currentCtxLoader =
|
||||
currentThread.getContextClassLoader();
|
||||
currentThread.setContextClassLoader(nonpublicLoaderB);
|
||||
|
||||
InvalidClassException invalid = null;
|
||||
try {
|
||||
unmarshalProxyClass(proxy4, fnnLoader2, nonpublicLoaderB,
|
||||
4, null);
|
||||
} catch (InvalidClassException e) {
|
||||
invalid = e;
|
||||
}
|
||||
|
||||
if (invalid == null) {
|
||||
TestLibrary.bomb("case4: InvalidClassException not thrown " +
|
||||
"when multiple nonpublic interfaces have \n" +
|
||||
"different class loaders");
|
||||
} else {
|
||||
System.err.println("\ncase4: InvalidClassException correctly " +
|
||||
"thrown \n when trying to load proxy " +
|
||||
"with multiple nonpublic interfaces in \n" +
|
||||
" different class loaders");
|
||||
}
|
||||
currentThread.setContextClassLoader(currentCtxLoader);
|
||||
|
||||
|
||||
|
||||
/* Case 5*/
|
||||
ClassLoader publicLoader =
|
||||
new URLClassLoader(new URL[] {publicUrl});
|
||||
Class publicInterface5 =
|
||||
publicLoader.loadClass("PublicInterface");
|
||||
Proxy proxy5 = (Proxy) Proxy.newProxyInstance(publicLoader,
|
||||
new Class[] {publicInterface5},
|
||||
new TestInvocationHandler());
|
||||
|
||||
currentCtxLoader =
|
||||
currentThread.getContextClassLoader();
|
||||
currentThread.setContextClassLoader(publicLoader);
|
||||
// unmarshalProxyClass(proxy5, fnnLoader2, publicLoader, 5,
|
||||
// new Case5Checker());
|
||||
currentThread.setContextClassLoader(currentCtxLoader);
|
||||
|
||||
|
||||
|
||||
/* Case 6 */
|
||||
ClassLoader fnnLoader6 =
|
||||
new URLClassLoader(new URL[] {fnnUrl, publicUrl});
|
||||
ClassLoader publicLoader6 =
|
||||
new URLClassLoader(new URL[] {publicUrl1}, fnnLoader6);
|
||||
|
||||
Class publicInterface6a =
|
||||
publicLoader6.loadClass("PublicInterface1");
|
||||
Class publicInterface6b =
|
||||
fnnLoader6.loadClass("PublicInterface");
|
||||
Proxy proxy6 = (Proxy) Proxy.newProxyInstance(publicLoader6,
|
||||
new Class[] {publicInterface6a, publicInterface6b},
|
||||
new TestInvocationHandler());
|
||||
ClassNotFoundException cnfe = null;
|
||||
try {
|
||||
unmarshalProxyClass(proxy6, fnnLoader6, publicLoader6, 6,
|
||||
null);
|
||||
} catch (ClassNotFoundException e) {
|
||||
cnfe = e;
|
||||
}
|
||||
if (cnfe == null) {
|
||||
TestLibrary.bomb("ClassNotFoundException not thrown " +
|
||||
"when not all proxy interfaces could " +
|
||||
" be found in a single class loader ");
|
||||
} else {
|
||||
System.err.println("Case6: ClassNotFoundException " +
|
||||
"correctly thrown when not all proxy" +
|
||||
" interfaces could be found in a " +
|
||||
"single class loader");
|
||||
cnfe.printStackTrace();
|
||||
}
|
||||
|
||||
System.err.println("TEST PASSED");
|
||||
|
||||
} catch (Exception e) {
|
||||
if (e instanceof RuntimeException) {
|
||||
throw (RuntimeException) e;
|
||||
}
|
||||
TestLibrary.bomb(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private interface LoadChecker {
|
||||
void checkLoad(Proxy proxy, ClassLoader expectedLoader);
|
||||
}
|
||||
|
||||
private static Proxy unmarshalProxyClass(Proxy proxy,
|
||||
ClassLoader fnnLoader,
|
||||
ClassLoader expectedLoader,
|
||||
int n,
|
||||
LoadChecker checker)
|
||||
throws ClassNotFoundException, IOException,
|
||||
InstantiationException, IllegalAccessException
|
||||
{
|
||||
FnnUnmarshal fnnUnmarshal = (FnnUnmarshal)
|
||||
fnnLoader.loadClass("FnnClass").newInstance();
|
||||
Proxy unmarshalled = (Proxy)
|
||||
fnnUnmarshal.unmarshal(new MarshalledObject(proxy));
|
||||
ClassLoader unmarshalledLoader =
|
||||
unmarshalled.getClass().getClassLoader();
|
||||
|
||||
if (checker != null) {
|
||||
checker.checkLoad(unmarshalled, expectedLoader);
|
||||
} else {
|
||||
if (unmarshalledLoader != expectedLoader) {
|
||||
TestLibrary.bomb("case" + n + ": proxy class not " +
|
||||
"placed into incorrect loader: " +
|
||||
unmarshalledLoader);
|
||||
} else {
|
||||
System.err.println("\ncase" + n + ": proxy class correctly" +
|
||||
" placed into expected loader: " +
|
||||
expectedLoader);
|
||||
}
|
||||
}
|
||||
return proxy;
|
||||
}
|
||||
|
||||
private static class Case3Checker implements LoadChecker {
|
||||
public void checkLoad(Proxy proxy, ClassLoader expectedLoader) {
|
||||
ClassLoader ifaceLoader =
|
||||
proxy.getClass().getInterfaces()[0].getClassLoader();
|
||||
ClassLoader proxyLoader = proxy.getClass().getClassLoader();
|
||||
|
||||
boolean proxyOk = false;
|
||||
|
||||
if (boomerangSemantics) {
|
||||
ClassLoader ctxLoader =
|
||||
Thread.currentThread().getContextClassLoader();
|
||||
if (proxyLoader == ctxLoader) {
|
||||
proxyOk = true;
|
||||
}
|
||||
} else if (proxyLoader.getClass().
|
||||
getName().indexOf("sun.rmi") >= 0)
|
||||
{
|
||||
proxyOk = true;
|
||||
}
|
||||
|
||||
if (proxyOk) {
|
||||
System.err.println("\ncase3: proxy loaded in" +
|
||||
" correct loader: " + proxyLoader +
|
||||
Arrays.asList(((URLClassLoader)
|
||||
proxyLoader).getURLs()));
|
||||
} else {
|
||||
TestLibrary.bomb("case3: proxy class loaded in " +
|
||||
"incorrect loader: " + proxyLoader +
|
||||
Arrays.asList(((URLClassLoader)
|
||||
proxyLoader).getURLs()));
|
||||
}
|
||||
|
||||
if (ifaceLoader == expectedLoader) {
|
||||
System.err.println("case3: proxy interface loaded in" +
|
||||
" correct loader: " + ifaceLoader);
|
||||
} else {
|
||||
TestLibrary.bomb("public proxy interface loaded in " +
|
||||
"incorrect loader: " + ifaceLoader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class Case5Checker implements LoadChecker {
|
||||
public void checkLoad(Proxy proxy, ClassLoader expectedLoader) {
|
||||
ClassLoader proxyLoader = proxy.getClass().getClassLoader();
|
||||
|
||||
String proxyAnnotation =
|
||||
RMIClassLoader.getClassAnnotation(proxy.getClass());
|
||||
|
||||
if ((proxyAnnotation == null) ||
|
||||
!proxyAnnotation.equals(publicUrl.toString()))
|
||||
{
|
||||
TestLibrary.bomb("proxy class had incorrect annotation: " +
|
||||
proxyAnnotation);
|
||||
} else {
|
||||
System.err.println("proxy class had correct annotation: " +
|
||||
proxyAnnotation);
|
||||
}
|
||||
|
||||
boolean proxyOk = false;
|
||||
|
||||
if (boomerangSemantics) {
|
||||
ClassLoader ctxLoader =
|
||||
Thread.currentThread().getContextClassLoader();
|
||||
if (proxyLoader == ctxLoader) {
|
||||
proxyOk = true;
|
||||
}
|
||||
} else if (proxyLoader.getClass().
|
||||
getName().indexOf("sun.rmi") >= 0)
|
||||
{
|
||||
proxyOk = true;
|
||||
}
|
||||
|
||||
if (proxyOk) {
|
||||
System.err.println("\ncase5: proxy loaded from" +
|
||||
" correct loader: " + proxyLoader);
|
||||
} else {
|
||||
TestLibrary.bomb("case5: proxy interface loaded from " +
|
||||
"incorrect loader: " + proxyLoader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class TestInvocationHandler
|
||||
implements InvocationHandler, Serializable
|
||||
{
|
||||
public Object invoke(Object proxy, Method method, Object[] args)
|
||||
throws Throwable {return null;}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
interface NonpublicInterface {}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
interface NonpublicInterface1 {}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
public interface PublicInterface {}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
public interface PublicInterface1 {}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 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.
|
||||
*/
|
||||
|
||||
public class Dummy {
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 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.
|
||||
*/
|
||||
|
||||
public class LocalDummy {
|
||||
}
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2012, 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 4140511
|
||||
* @summary RMIClassLoader's loadClass() methods, when there is no security
|
||||
* manager installed, should not create or use RMI class loader instances for
|
||||
* the requested codebases, but they should still succeed to load classes
|
||||
* that can be found by delegation to parent class loader that would have
|
||||
* been used for the RMI class loader instance.
|
||||
* @author Peter Jones
|
||||
*
|
||||
* @build Dummy LocalDummy
|
||||
* @run main/othervm/timeout=120 NoSecurityManager
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.security.*;
|
||||
import java.rmi.server.RMIClassLoader;
|
||||
|
||||
/**
|
||||
* NoSecurityManager verifies the behavior of the RMIClassLoader.loadClass()
|
||||
* methods when there is no security manager installed in JDK1.2 as prescribed
|
||||
* by RFE 4140511.
|
||||
*
|
||||
* First, a class installed in a codebase (and not in the test's class path)
|
||||
* is loaded using RMIClassLoader.loadClass(); this should fail with a
|
||||
* ClassNotFoundException (it failed with a SecurityException in JDK 1.1).
|
||||
*
|
||||
* Second, a class installed in the test's class path is loaded using
|
||||
* RMIClassLoader.loadClass(), which should succeed (again, this used
|
||||
* to fail with a SecurityException in JDK 1.1).
|
||||
*/
|
||||
public class NoSecurityManager {
|
||||
|
||||
/** name of target class to attempt to load */
|
||||
private static final String className = "Dummy";
|
||||
|
||||
/** name of file containing definition for target class */
|
||||
private static final String classFileName = className + ".class";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
/*
|
||||
* Specify the file to contain the class definition.
|
||||
* Make sure that there is a "classes" subdirectory underneath
|
||||
* the working directory to be used as the codebase for the
|
||||
* class definition to be located.
|
||||
*/
|
||||
File dstDir = new File(System.getProperty("user.dir"), "codebase");
|
||||
if (!dstDir.exists()) {
|
||||
if (!dstDir.mkdir()) {
|
||||
throw new RuntimeException(
|
||||
"could not create codebase directory");
|
||||
}
|
||||
}
|
||||
File dstFile = new File(dstDir, classFileName);
|
||||
|
||||
/*
|
||||
* Specify where we will copy the class definition from, if
|
||||
* necessary. After the test is built, the class file can be
|
||||
* found in the "test.classes" directory.
|
||||
*/
|
||||
File srcDir = new File(System.getProperty("test.classes", "."));
|
||||
File srcFile = new File(srcDir, classFileName);
|
||||
|
||||
/*
|
||||
* If the class definition is not already located at the codebase,
|
||||
* copy it there from the test build area.
|
||||
*/
|
||||
if (!dstFile.exists()) {
|
||||
if (!srcFile.exists()) {
|
||||
throw new RuntimeException(
|
||||
"could not find class file to install in codebase " +
|
||||
"(try rebuilding the test)");
|
||||
}
|
||||
if (!srcFile.renameTo(dstFile)) {
|
||||
throw new RuntimeException(
|
||||
"could not install class file in codebase");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* After the class definition is successfully installed at the
|
||||
* codebase, delete it from the test's CLASSPATH, so that it will
|
||||
* not be found there first before the codebase is searched.
|
||||
*/
|
||||
if (srcFile.exists()) {
|
||||
if (!srcFile.delete()) {
|
||||
throw new RuntimeException(
|
||||
"could not delete duplicate class file in CLASSPATH");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Obtain the URL for the codebase.
|
||||
*/
|
||||
URL codebaseURL = new URL("file", "",
|
||||
dstDir.getAbsolutePath().replace(File.separatorChar, '/') + "/");
|
||||
|
||||
/*
|
||||
* No security manager has been set: verify that we cannot load
|
||||
* a class from a specified codebase (that is not in the class path).
|
||||
*/
|
||||
try {
|
||||
RMIClassLoader.loadClass(codebaseURL, className);
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: class loaded successfully from codebase");
|
||||
} catch (ClassNotFoundException e) {
|
||||
System.err.println(e.toString());
|
||||
}
|
||||
|
||||
/*
|
||||
* No security manager has been set: verify that we can still
|
||||
* load a class available in the context class loader (class path).
|
||||
*/
|
||||
RMIClassLoader.loadClass(codebaseURL, "LocalDummy");
|
||||
System.err.println("TEST PASSED: local class loaded successfully");
|
||||
|
||||
/*
|
||||
* Verify that getClassLoader returns context class loader
|
||||
* if no security manager is set.
|
||||
*/
|
||||
System.err.println("/nTest getClassLoader with no security manager set");
|
||||
ClassLoader loader = RMIClassLoader.getClassLoader("http://codebase");
|
||||
if (loader == Thread.currentThread().getContextClassLoader()) {
|
||||
System.err.println("TEST PASSED: returned context class loader");
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: returned RMI-created class loader");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2024, 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 4418673
|
||||
* @summary verify that setting the java.rmi.server.RMIClassLoaderSpi
|
||||
* system property to "default" causes the default provider instance to
|
||||
* be used by the RMIClassLoader API.
|
||||
* @author Peter Jones
|
||||
*
|
||||
* @library ../../../testlibrary
|
||||
* @modules java.rmi/java.rmi.server:+open
|
||||
* java.rmi/sun.rmi.registry
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary ServiceConfiguration
|
||||
* @run main/othervm DefaultProperty
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.rmi.server.RMIClassLoader;
|
||||
import java.rmi.server.RMIClassLoaderSpi;
|
||||
|
||||
public class DefaultProperty {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
ServiceConfiguration.installServiceConfigurationFile();
|
||||
|
||||
System.setProperty(
|
||||
"java.rmi.server.RMIClassLoaderSpi", "default");
|
||||
|
||||
// Force loading of RMIClassLoader, which will initialize the
|
||||
// provider instance.
|
||||
RMIClassLoaderSpi def = RMIClassLoader.getDefaultProviderInstance();
|
||||
|
||||
Field fProvider = RMIClassLoader.class.getDeclaredField("provider");
|
||||
fProvider.setAccessible(true);
|
||||
RMIClassLoaderSpi actual = (RMIClassLoaderSpi) fProvider.get(null);
|
||||
|
||||
if (def != actual) {
|
||||
System.err.println("TEST FAILED");
|
||||
System.err.println("default provider = " + def);
|
||||
System.err.println("actual provider = " + actual);
|
||||
throw new AssertionError("TEST FAILED");
|
||||
}
|
||||
|
||||
System.err.println("TEST PASSED");
|
||||
}
|
||||
}
|
||||
25
test/jdk/java/rmi/server/RMIClassLoader/spi/Foo.java
Normal file
25
test/jdk/java/rmi/server/RMIClassLoader/spi/Foo.java
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 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.
|
||||
*/
|
||||
|
||||
public class Foo {
|
||||
}
|
||||
52
test/jdk/java/rmi/server/RMIClassLoader/spi/Installed.java
Normal file
52
test/jdk/java/rmi/server/RMIClassLoader/spi/Installed.java
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2024, 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 4418673
|
||||
* @summary verify that with the java.rmi.server.RMIClassLoaderSpi system
|
||||
* property not set, the first provider located through java.util.ServiceLoader
|
||||
* (which should be "TestProvider2") will be used by the RMIClassLoader API.
|
||||
* @author Peter Jones
|
||||
*
|
||||
* @library ../../../testlibrary
|
||||
* @modules java.rmi/sun.rmi.registry
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary ServiceConfiguration TestProvider TestProvider2
|
||||
* @run main/othervm Installed
|
||||
*/
|
||||
|
||||
public class Installed {
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
ServiceConfiguration.installServiceConfigurationFile();
|
||||
|
||||
TestProvider.exerciseTestProvider(
|
||||
TestProvider2.loadClassReturn,
|
||||
TestProvider2.loadProxyClassReturn,
|
||||
TestProvider2.getClassLoaderReturn,
|
||||
TestProvider2.getClassAnnotationReturn,
|
||||
TestProvider2.invocations);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2024, 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 4418673
|
||||
* @summary verify that an inavlid setting of the system property
|
||||
* java.rmi.server.RMIClassLoaderSpi causes an Error to be thrown to users
|
||||
* of the RMIClassLoader API.
|
||||
* @author Peter Jones
|
||||
*
|
||||
* @library ../../../testlibrary
|
||||
* @modules java.rmi/sun.rmi.registry
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary ServiceConfiguration
|
||||
* @run main/othervm InvalidProperty
|
||||
*/
|
||||
|
||||
import java.rmi.server.RMIClassLoader;
|
||||
|
||||
public class InvalidProperty {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
ServiceConfiguration.installServiceConfigurationFile();
|
||||
|
||||
System.setProperty(
|
||||
"java.rmi.server.RMIClassLoaderSpi", "NonexistentProvider");
|
||||
|
||||
String classname = "Foo";
|
||||
|
||||
try {
|
||||
System.err.println("first attempt:");
|
||||
Object ret;
|
||||
try {
|
||||
ret = RMIClassLoader.loadClass(classname);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(
|
||||
"RMIClassLoader.loadClass threw exception", e);
|
||||
}
|
||||
throw new RuntimeException(
|
||||
"RMIClassLoader.loadClass returned " + ret);
|
||||
} catch (Error e) {
|
||||
System.err.println("RMIClassLoader.loadClass threw an Error:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
try {
|
||||
System.err.println("second attempt:");
|
||||
Object ret;
|
||||
try {
|
||||
ret = RMIClassLoader.loadClass(classname);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(
|
||||
"RMIClassLoader.loadClass threw exception", e);
|
||||
}
|
||||
throw new RuntimeException(
|
||||
"RMIClassLoader.loadClass returned " + ret);
|
||||
} catch (Error e) {
|
||||
System.err.println("RMIClassLoader.loadClass threw an Error:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
System.err.println("TEST PASSED");
|
||||
}
|
||||
}
|
||||
55
test/jdk/java/rmi/server/RMIClassLoader/spi/Property.java
Normal file
55
test/jdk/java/rmi/server/RMIClassLoader/spi/Property.java
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2024, 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 4418673
|
||||
* @summary verify that the value of the java.rmi.server.RMIClassLoaderSpi
|
||||
* system property is interpreted to name the class to instantiate for the
|
||||
* RMIClassLoader provider.
|
||||
* @author Peter Jones
|
||||
*
|
||||
* @library ../../../testlibrary
|
||||
* @modules java.rmi/sun.rmi.registry
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary ServiceConfiguration TestProvider
|
||||
* @run main/othervm Property
|
||||
*/
|
||||
|
||||
public class Property {
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
ServiceConfiguration.installServiceConfigurationFile();
|
||||
|
||||
System.setProperty(
|
||||
"java.rmi.server.RMIClassLoaderSpi", "TestProvider");
|
||||
|
||||
TestProvider.exerciseTestProvider(
|
||||
TestProvider.loadClassReturn,
|
||||
TestProvider.loadProxyClassReturn,
|
||||
TestProvider.getClassLoaderReturn,
|
||||
TestProvider.getClassAnnotationReturn,
|
||||
TestProvider.invocations);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
public class ServiceConfiguration {
|
||||
public static void installServiceConfigurationFile() {
|
||||
String filename = "java.rmi.server.RMIClassLoaderSpi";
|
||||
|
||||
File dstDir = new File(TestLibrary.getProperty("test.classes", "."),
|
||||
"META-INF/services");
|
||||
if (!dstDir.exists()) {
|
||||
if (!dstDir.mkdirs()) {
|
||||
throw new RuntimeException(
|
||||
"could not create META-INF/services directory " + dstDir);
|
||||
}
|
||||
}
|
||||
File dstFile = new File(dstDir, filename);
|
||||
|
||||
File srcDir = new File(TestLibrary.getProperty("test.src", "."));
|
||||
File srcFile = new File(srcDir, filename);
|
||||
|
||||
try {
|
||||
TestLibrary.copyFile(srcFile, dstFile);
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("could not install " + dstFile, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
278
test/jdk/java/rmi/server/RMIClassLoader/spi/TestProvider.java
Normal file
278
test/jdk/java/rmi/server/RMIClassLoader/spi/TestProvider.java
Normal file
|
|
@ -0,0 +1,278 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import java.rmi.server.RMIClassLoader;
|
||||
import java.rmi.server.RMIClassLoaderSpi;
|
||||
|
||||
public class TestProvider extends RMIClassLoaderSpi {
|
||||
|
||||
public static final Method loadClassMethod;
|
||||
public static final Method loadProxyClassMethod;
|
||||
public static final Method getClassLoaderMethod;
|
||||
public static final Method getClassAnnotationMethod;
|
||||
static {
|
||||
try {
|
||||
loadClassMethod = RMIClassLoaderSpi.class.getMethod(
|
||||
"loadClass", new Class[] {
|
||||
String.class, String.class, ClassLoader.class
|
||||
});
|
||||
loadProxyClassMethod = RMIClassLoaderSpi.class.getMethod(
|
||||
"loadProxyClass", new Class[] {
|
||||
String.class, String[].class, ClassLoader.class
|
||||
});
|
||||
getClassLoaderMethod = RMIClassLoaderSpi.class.getMethod(
|
||||
"getClassLoader", new Class[] { String.class });
|
||||
getClassAnnotationMethod = RMIClassLoaderSpi.class.getMethod(
|
||||
"getClassAnnotation", new Class[] { Class.class });
|
||||
} catch (NoSuchMethodException e) {
|
||||
Error error = new NoSuchMethodError();
|
||||
error.initCause(e);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
public static final Class loadClassReturn =
|
||||
(new Object() { }).getClass();
|
||||
public static final Class loadProxyClassReturn =
|
||||
(new Object() { }).getClass();
|
||||
public static final ClassLoader getClassLoaderReturn =
|
||||
URLClassLoader.newInstance(new URL[0]);
|
||||
public static final String getClassAnnotationReturn = new String();
|
||||
|
||||
public static List invocations =
|
||||
Collections.synchronizedList(new ArrayList(1));
|
||||
|
||||
public TestProvider() {
|
||||
System.err.println("TestProvider()");
|
||||
}
|
||||
|
||||
public Class loadClass(String codebase, String name,
|
||||
ClassLoader defaultLoader)
|
||||
throws MalformedURLException, ClassNotFoundException
|
||||
{
|
||||
invocations.add(new Invocation(loadClassMethod,
|
||||
new Object[] { codebase, name, defaultLoader }));
|
||||
|
||||
return loadClassReturn;
|
||||
}
|
||||
|
||||
public Class loadProxyClass(String codebase, String[] interfaces,
|
||||
ClassLoader defaultLoader)
|
||||
throws MalformedURLException, ClassNotFoundException
|
||||
{
|
||||
invocations.add(new Invocation(loadProxyClassMethod,
|
||||
new Object[] { codebase, interfaces, defaultLoader }));
|
||||
|
||||
return loadProxyClassReturn;
|
||||
}
|
||||
|
||||
public ClassLoader getClassLoader(String codebase)
|
||||
throws MalformedURLException
|
||||
{
|
||||
invocations.add(new Invocation(
|
||||
getClassLoaderMethod, new Object[] { codebase }));
|
||||
|
||||
return getClassLoaderReturn;
|
||||
}
|
||||
|
||||
public String getClassAnnotation(Class<?> cl) {
|
||||
invocations.add(new Invocation(
|
||||
getClassAnnotationMethod, new Object[] { cl }));
|
||||
|
||||
return getClassAnnotationReturn;
|
||||
}
|
||||
|
||||
public static class Invocation {
|
||||
public Method method;
|
||||
public Object[] args;
|
||||
|
||||
public Invocation(Method method, Object[] args) {
|
||||
this.method = method;
|
||||
this.args = (Object[]) args.clone();
|
||||
}
|
||||
}
|
||||
|
||||
public static void exerciseTestProvider(Object loadClassReturn,
|
||||
Object loadProxyClassReturn,
|
||||
Object getClassLoaderReturn,
|
||||
Object getClassAnnotationReturn,
|
||||
List invocationQueue)
|
||||
throws MalformedURLException, ClassNotFoundException
|
||||
{
|
||||
URL codebaseURL = new URL("http://the-black-lodge/dale-cooper/");
|
||||
String codebase = codebaseURL.toString();
|
||||
String classname = "Foo";
|
||||
ClassLoader defaultLoader = URLClassLoader.newInstance(new URL[0]);
|
||||
String[] interfaces = new String[] { "Bar", "Baz" };
|
||||
Class dummyClass = (new Object() { }).getClass();
|
||||
|
||||
String testcase;
|
||||
Object ret;
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
testcase = "RMIClassLoader.loadClass(String)";
|
||||
System.err.println("testing " + testcase);
|
||||
|
||||
ret = RMIClassLoader.loadClass(classname);
|
||||
if (ret != loadClassReturn) {
|
||||
throw new RuntimeException("TEST FAILED: " +
|
||||
testcase + " returned " + ret);
|
||||
}
|
||||
verifyOneInvocation(TestProvider.loadClassMethod,
|
||||
new Object[] { null, classname, null }, invocationQueue);
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
testcase = "RMIClassLoader.loadClass(URL,String)";
|
||||
System.err.println("testing " + testcase);
|
||||
|
||||
ret = RMIClassLoader.loadClass(codebaseURL, classname);
|
||||
if (ret != loadClassReturn) {
|
||||
throw new RuntimeException("TEST FAILED: " +
|
||||
testcase + " returned " + ret);
|
||||
}
|
||||
verifyOneInvocation(TestProvider.loadClassMethod,
|
||||
new Object[] { codebase, classname, null }, invocationQueue);
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
testcase = "RMIClassLoader.loadClass(String,String)";
|
||||
System.err.println("testing " + testcase);
|
||||
|
||||
ret = RMIClassLoader.loadClass(codebase, classname);
|
||||
if (ret != loadClassReturn) {
|
||||
throw new RuntimeException("TEST FAILED: " +
|
||||
testcase + " returned " + ret);
|
||||
}
|
||||
verifyOneInvocation(TestProvider.loadClassMethod,
|
||||
new Object[] { codebase, classname, null }, invocationQueue);
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
testcase = "RMIClassLoader.loadClass(String,String,ClassLoader";
|
||||
System.err.println("testing " + testcase);
|
||||
|
||||
ret = RMIClassLoader.loadClass(codebase, classname, defaultLoader);
|
||||
if (ret != loadClassReturn) {
|
||||
throw new RuntimeException("TEST FAILED: " +
|
||||
testcase + " returned " + ret);
|
||||
}
|
||||
verifyOneInvocation(TestProvider.loadClassMethod,
|
||||
new Object[] { codebase, classname, defaultLoader },
|
||||
invocationQueue);
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
testcase =
|
||||
"RMIClassLoader.loadProxyClass(String,String[],ClassLoader)";
|
||||
System.err.println("testing " + testcase);
|
||||
|
||||
ret = RMIClassLoader.loadProxyClass(codebase, interfaces,
|
||||
defaultLoader);
|
||||
if (ret != loadProxyClassReturn) {
|
||||
throw new RuntimeException("TEST FAILED: " +
|
||||
testcase + " returned " + ret);
|
||||
}
|
||||
verifyOneInvocation(TestProvider.loadProxyClassMethod,
|
||||
new Object[] { codebase, interfaces, defaultLoader },
|
||||
invocationQueue);
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
testcase = "RMIClassLoader.getClassLoader(String)";
|
||||
System.err.println("testing " + testcase);
|
||||
|
||||
ret = RMIClassLoader.getClassLoader(codebase);
|
||||
if (ret != getClassLoaderReturn) {
|
||||
throw new RuntimeException("TEST FAILED: " +
|
||||
testcase + " returned " + ret);
|
||||
}
|
||||
verifyOneInvocation(TestProvider.getClassLoaderMethod,
|
||||
new Object[] { codebase }, invocationQueue);
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
testcase = "RMIClassLoader.getClassAnnotation(Class)";
|
||||
System.err.println("testing " + testcase);
|
||||
|
||||
ret = RMIClassLoader.getClassAnnotation(dummyClass);
|
||||
if (ret != getClassAnnotationReturn) {
|
||||
throw new RuntimeException("TEST FAILED: " +
|
||||
testcase + " returned " + ret);
|
||||
}
|
||||
verifyOneInvocation(TestProvider.getClassAnnotationMethod,
|
||||
new Object[] { dummyClass }, invocationQueue);
|
||||
|
||||
System.err.println("TEST PASSED");
|
||||
}
|
||||
|
||||
private static void verifyOneInvocation(Method method, Object[] args,
|
||||
List invocationQueue)
|
||||
{
|
||||
TestProvider.Invocation inv =
|
||||
(TestProvider.Invocation) invocationQueue.remove(0);
|
||||
|
||||
if (!method.equals(inv.method)) {
|
||||
throw new RuntimeException(
|
||||
"unexpected provider method invoked: expected " + method +
|
||||
", detected " + inv.method);
|
||||
}
|
||||
|
||||
List expectedArgs = Arrays.asList(args);
|
||||
List detectedArgs = Arrays.asList(inv.args);
|
||||
if (!expectedArgs.equals(detectedArgs)) {
|
||||
throw new RuntimeException("TEST FAILED: " +
|
||||
"unexpected provider method invocation arguments: " +
|
||||
"expected " + expectedArgs + ", detected " + detectedArgs);
|
||||
}
|
||||
|
||||
if (!invocationQueue.isEmpty()) {
|
||||
inv = (TestProvider.Invocation)
|
||||
invocationQueue.remove(0);
|
||||
throw new RuntimeException("TEST FAILED: " +
|
||||
"unexpected provider invocation: " + inv.method + " " +
|
||||
Arrays.asList(inv.args));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2004, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import java.rmi.server.RMIClassLoader;
|
||||
import java.rmi.server.RMIClassLoaderSpi;
|
||||
|
||||
/**
|
||||
* TestProvider2 extends TestProvider with very similar behavior, but
|
||||
* with its own static fields, to allow a test to distinguish between
|
||||
* an installed TestProvider2 being used, or a property-specified
|
||||
* TestProvider being used.
|
||||
*/
|
||||
public class TestProvider2 extends TestProvider {
|
||||
|
||||
public static final Class loadClassReturn =
|
||||
(new Object() { }).getClass();
|
||||
public static final Class loadProxyClassReturn =
|
||||
(new Object() { }).getClass();
|
||||
public static final ClassLoader getClassLoaderReturn =
|
||||
URLClassLoader.newInstance(new URL[0]);
|
||||
public static final String getClassAnnotationReturn = new String();
|
||||
|
||||
public static List invocations =
|
||||
Collections.synchronizedList(new ArrayList(1));
|
||||
|
||||
public TestProvider2() {
|
||||
System.err.println("TestProvider2()");
|
||||
}
|
||||
|
||||
public Class loadClass(String codebase, String name,
|
||||
ClassLoader defaultLoader)
|
||||
throws MalformedURLException, ClassNotFoundException
|
||||
{
|
||||
invocations.add(new Invocation(loadClassMethod,
|
||||
new Object[] { codebase, name, defaultLoader }));
|
||||
|
||||
return loadClassReturn;
|
||||
}
|
||||
|
||||
public Class loadProxyClass(String codebase, String[] interfaces,
|
||||
ClassLoader defaultLoader)
|
||||
throws MalformedURLException, ClassNotFoundException
|
||||
{
|
||||
invocations.add(new Invocation(loadProxyClassMethod,
|
||||
new Object[] { codebase, interfaces, defaultLoader }));
|
||||
|
||||
return loadProxyClassReturn;
|
||||
}
|
||||
|
||||
public ClassLoader getClassLoader(String codebase)
|
||||
throws MalformedURLException
|
||||
{
|
||||
invocations.add(new Invocation(
|
||||
getClassLoaderMethod, new Object[] { codebase }));
|
||||
|
||||
return getClassLoaderReturn;
|
||||
}
|
||||
|
||||
public String getClassAnnotation(Class<?> cl) {
|
||||
invocations.add(new Invocation(
|
||||
getClassAnnotationMethod, new Object[] { cl }));
|
||||
|
||||
return getClassAnnotationReturn;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
TestProvider2
|
||||
TestProvider3
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 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.
|
||||
*/
|
||||
|
||||
public class Bar implements java.io.Serializable {
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 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.
|
||||
*/
|
||||
|
||||
public class Foo implements java.io.Serializable {
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
public interface Receiver extends Remote {
|
||||
public void receive(Object obj) throws RemoteException;
|
||||
}
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2024, 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 4174006
|
||||
* @summary If the "java.rmi.server.useCodebaseOnly" property has a boolean
|
||||
* value of true, then when the RMI runtime is unmarshalling a class
|
||||
* descriptor, it should not attempt to download the associate Class object
|
||||
* from the annotated codebase, but only from the codebase specified in the
|
||||
* "java.rmi.server.codebase" property and the context class loader.
|
||||
* @author Peter Jones
|
||||
*
|
||||
* @library ../../../testlibrary
|
||||
* @modules java.rmi/sun.rmi.registry
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary Receiver UseCodebaseOnly_Stub Foo Bar TestLoaderHandler
|
||||
* @run main/othervm UseCodebaseOnly
|
||||
*/
|
||||
|
||||
import java.net.*;
|
||||
import java.rmi.*;
|
||||
import java.rmi.server.*;
|
||||
|
||||
public class UseCodebaseOnly
|
||||
extends UnicastRemoteObject
|
||||
implements Receiver
|
||||
{
|
||||
|
||||
public UseCodebaseOnly() throws RemoteException {
|
||||
}
|
||||
|
||||
public void receive(Object obj) {
|
||||
System.err.println("+ receive(): received object " + obj);
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
System.err.println("\nRegression test for bug 4174006\n");
|
||||
|
||||
System.setProperty("java.rmi.server.RMIClassLoaderSpi", "TestLoaderHandler");
|
||||
|
||||
URL localCodebase = null, remoteCodebase = null;
|
||||
try {
|
||||
remoteCodebase =
|
||||
TestLibrary.installClassInCodebase("Foo", "remote_codebase");
|
||||
localCodebase =
|
||||
TestLibrary.installClassInCodebase("Bar", "local_codebase");
|
||||
} catch (MalformedURLException e) {
|
||||
TestLibrary.bomb(e);
|
||||
}
|
||||
|
||||
TestLibrary.setProperty("java.rmi.server.useCodebaseOnly", "true");
|
||||
TestLibrary.setProperty( // set local codebase property
|
||||
"java.rmi.server.codebase", localCodebase.toString());
|
||||
|
||||
/*
|
||||
* Load Foo and Bar from non-RMI class loaders so that they won't be
|
||||
* already loaded by RMI class loaders in this VM (for whatever that's
|
||||
* worth), but with URLClassLoader so that they will be annotated
|
||||
* properly.
|
||||
*/
|
||||
System.err.println("Creating class loader for remote codebase " +
|
||||
remoteCodebase);
|
||||
ClassLoader remoteCodebaseLoader =
|
||||
URLClassLoader.newInstance(new URL[] { remoteCodebase });
|
||||
System.err.println("Creating class loader for local codebase " +
|
||||
localCodebase);
|
||||
ClassLoader localCodebaseLoader =
|
||||
URLClassLoader.newInstance(new URL[] { localCodebase });
|
||||
|
||||
System.err.println("Creating remote object.");
|
||||
UseCodebaseOnly obj = null;
|
||||
try {
|
||||
obj = new UseCodebaseOnly();
|
||||
} catch (RemoteException e) {
|
||||
TestLibrary.bomb(e);
|
||||
}
|
||||
|
||||
try {
|
||||
Receiver stub = (Receiver) RemoteObject.toStub(obj);
|
||||
|
||||
/*
|
||||
* Pass an instance of Bar, the class in the local codebase.
|
||||
* This should succeed, because the server is allow to load
|
||||
* classes from the local codebase.
|
||||
*/
|
||||
System.err.println(
|
||||
"Passing class from local codebase (should succeed).");
|
||||
Class barClass = localCodebaseLoader.loadClass("Bar");
|
||||
Object barObj = barClass.newInstance();
|
||||
stub.receive(barObj);
|
||||
|
||||
/*
|
||||
* Pass an instance of Foo, the class in the remote codebase.
|
||||
* This should fail, because the server is not allowed to load
|
||||
* classes from other codebases besides the local codebase.
|
||||
*/
|
||||
System.err.println(
|
||||
"Passing class from remote codebase (should fail).");
|
||||
Class fooClass = remoteCodebaseLoader.loadClass("Foo");
|
||||
Object fooObj = fooClass.newInstance();
|
||||
try {
|
||||
stub.receive(fooObj);
|
||||
throw new RuntimeException("TEST FAILED: " +
|
||||
"class from remote codebase sucesssfully unmarshalled");
|
||||
} catch (RemoteException e) {
|
||||
/*
|
||||
* Verify that the failure was that the server couldn't
|
||||
* unmarshal the Foo class.
|
||||
*/
|
||||
if ((e instanceof ServerException) &&
|
||||
(e.detail instanceof UnmarshalException) &&
|
||||
(((RemoteException) e.detail).detail instanceof
|
||||
ClassNotFoundException) &&
|
||||
(((RemoteException) e.detail).detail.getMessage().equals(
|
||||
"Foo")))
|
||||
{
|
||||
System.err.println("TEST PASSED: ");
|
||||
e.printStackTrace();
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.err.println("TEST FAILED: ");
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("TEST FAILED: " + e.toString());
|
||||
} finally {
|
||||
try {
|
||||
UnicastRemoteObject.unexportObject(obj, true);
|
||||
} catch (Throwable e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 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.
|
||||
*/
|
||||
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class UseCodebaseOnly_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements Receiver, java.rmi.Remote
|
||||
{
|
||||
private static final java.rmi.server.Operation[] operations = {
|
||||
new java.rmi.server.Operation("void receive(java.lang.Object)")
|
||||
};
|
||||
|
||||
private static final long interfaceHash = -953299374608818732L;
|
||||
|
||||
private static final long serialVersionUID = 2;
|
||||
|
||||
private static boolean useNewInvoke;
|
||||
private static java.lang.reflect.Method $method_receive_0;
|
||||
|
||||
static {
|
||||
try {
|
||||
java.rmi.server.RemoteRef.class.getMethod("invoke",
|
||||
new java.lang.Class[] {
|
||||
java.rmi.Remote.class,
|
||||
java.lang.reflect.Method.class,
|
||||
java.lang.Object[].class,
|
||||
long.class
|
||||
});
|
||||
useNewInvoke = true;
|
||||
$method_receive_0 = Receiver.class.getMethod("receive", new java.lang.Class[] {java.lang.Object.class});
|
||||
} catch (java.lang.NoSuchMethodException e) {
|
||||
useNewInvoke = false;
|
||||
}
|
||||
}
|
||||
|
||||
// constructors
|
||||
public UseCodebaseOnly_Stub() {
|
||||
super();
|
||||
}
|
||||
public UseCodebaseOnly_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
// methods from remote interfaces
|
||||
|
||||
// implementation of receive(Object)
|
||||
public void receive(java.lang.Object $param_Object_1)
|
||||
throws java.rmi.RemoteException
|
||||
{
|
||||
try {
|
||||
if (useNewInvoke) {
|
||||
ref.invoke(this, $method_receive_0, new java.lang.Object[] {$param_Object_1}, -578858472643205929L);
|
||||
} else {
|
||||
java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash);
|
||||
try {
|
||||
java.io.ObjectOutput out = call.getOutputStream();
|
||||
out.writeObject($param_Object_1);
|
||||
} catch (java.io.IOException e) {
|
||||
throw new java.rmi.MarshalException("error marshalling arguments", e);
|
||||
}
|
||||
ref.invoke(call);
|
||||
ref.done(call);
|
||||
}
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.rmi.RemoteException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (c) 2013, 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 8001040
|
||||
* @summary Tests proper parsing and defaulting of the
|
||||
* "java.rmi.server.useCodebaseOnly" property.
|
||||
*
|
||||
* @modules java.rmi/sun.rmi.server:+open
|
||||
* @run main/othervm UseCodebaseOnlyDefault true
|
||||
* @run main/othervm -Djava.rmi.server.useCodebaseOnly=xyzzy UseCodebaseOnlyDefault true
|
||||
* @run main/othervm -Djava.rmi.server.useCodebaseOnly UseCodebaseOnlyDefault true
|
||||
* @run main/othervm -Djava.rmi.server.useCodebaseOnly=true UseCodebaseOnlyDefault true
|
||||
* @run main/othervm -Djava.rmi.server.useCodebaseOnly=false UseCodebaseOnlyDefault false
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import sun.rmi.server.MarshalInputStream;
|
||||
|
||||
/**
|
||||
* usage: UseCodebaseOnlyDefault expected
|
||||
*
|
||||
* 'expected' is the expected value of useCodebaseOnly, which
|
||||
* must be "true" or "false".
|
||||
*/
|
||||
public class UseCodebaseOnlyDefault {
|
||||
static final String USAGE = "usage: UseCodebaseOnlyDefault boolean";
|
||||
static final String PROPNAME = "java.rmi.server.useCodebaseOnly";
|
||||
|
||||
/**
|
||||
* Gets the actual useCodebaseOnly value by creating an instance
|
||||
* of MarshalInputStream and reflecting on the useCodebaseOnly field.
|
||||
*/
|
||||
static boolean getActualValue() throws Exception {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||
oos.writeObject("foo");
|
||||
oos.close();
|
||||
|
||||
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
|
||||
MarshalInputStream mis = new MarshalInputStream(bais);
|
||||
|
||||
Field f = MarshalInputStream.class.getDeclaredField("useCodebaseOnly");
|
||||
f.setAccessible(true);
|
||||
return f.getBoolean(mis);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
if (args.length != 1) {
|
||||
throw new IllegalArgumentException(USAGE);
|
||||
}
|
||||
|
||||
boolean expected;
|
||||
if (args[0].equals("true")) {
|
||||
expected = true;
|
||||
} else if (args[0].equals("false")) {
|
||||
expected = false;
|
||||
} else {
|
||||
throw new IllegalArgumentException(USAGE);
|
||||
}
|
||||
System.out.println("expected = " + expected);
|
||||
|
||||
String prop = System.getProperty(PROPNAME);
|
||||
System.out.print("Property " + PROPNAME);
|
||||
if (prop == null) {
|
||||
System.out.println(" is not set");
|
||||
} else {
|
||||
System.out.println(" = '" + prop + "'");
|
||||
}
|
||||
|
||||
boolean actual = getActualValue();
|
||||
System.out.println("actual = " + actual);
|
||||
|
||||
if (expected != actual)
|
||||
throw new AssertionError("actual does not match expected value");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 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.
|
||||
*/
|
||||
|
||||
public class Dummy {
|
||||
}
|
||||
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2024, 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 4137605
|
||||
* @summary When the RMIClassLoader.getClassAnnotation() is called with a
|
||||
* class loaded from any URLClassLoader instance (not just those created for
|
||||
* internal use by the RMI runtime), then it should return a String containing
|
||||
* a space-separated list of the class loader's path of URLs.
|
||||
* @author Peter Jones
|
||||
*
|
||||
* @library ../../../testlibrary
|
||||
* @modules java.rmi/sun.rmi.registry
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary Dummy
|
||||
* @run main/othervm/timeout=120 UseGetURLs
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import java.rmi.*;
|
||||
import java.rmi.server.*;
|
||||
|
||||
public class UseGetURLs {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
System.err.println("\nRegression test for bug 4137605\n");
|
||||
|
||||
/*
|
||||
* Install dummy class in first codebase to be loaded from an
|
||||
* arbitrary URLClassLoader; the second codebase is used to make
|
||||
* the desired annotation more interesting (more than one element).
|
||||
*/
|
||||
URL codebase1 = null;
|
||||
URL codebase2 = null;
|
||||
try {
|
||||
codebase1 = TestLibrary.installClassInCodebase("Dummy",
|
||||
"codebase1");
|
||||
|
||||
File cb2file =
|
||||
new File(TestLibrary.getProperty("user.dir", "."),
|
||||
"codebase2");
|
||||
codebase2 = cb2file.toURL();
|
||||
} catch (MalformedURLException e) {
|
||||
TestLibrary.bomb("failed to install test classes", e);
|
||||
}
|
||||
|
||||
try {
|
||||
/*
|
||||
* Create an arbitary URLClassLoader for the two codebases.
|
||||
*/
|
||||
ClassLoader loader = URLClassLoader.newInstance(
|
||||
new URL[] { codebase1, codebase2 });
|
||||
System.err.println(
|
||||
"URLs for class loader: " +
|
||||
Arrays.asList(((URLClassLoader) loader).getURLs()));
|
||||
System.err.println("Expecting annotation: \"" +
|
||||
codebase1 + " " + codebase2 + "\"");
|
||||
System.err.println("First URL:");
|
||||
dumpURL(codebase1);
|
||||
System.err.println("Second URL:");
|
||||
dumpURL(codebase2);
|
||||
|
||||
/*
|
||||
* Load dummy class from the loader, get the annotation string,
|
||||
* and verify that it is correct.
|
||||
*/
|
||||
Class cl = loader.loadClass("Dummy");
|
||||
String annotation = RMIClassLoader.getClassAnnotation(cl);
|
||||
System.err.println("Received annotation: \"" +
|
||||
annotation + "\"");
|
||||
|
||||
if (annotation == null) {
|
||||
throw new RuntimeException("annotation was null");
|
||||
}
|
||||
URL[] urls = pathToURLs(annotation);
|
||||
System.err.println(
|
||||
"URLs from annotation: " + Arrays.asList(urls));
|
||||
if (urls.length != 2) {
|
||||
throw new RuntimeException(
|
||||
"wrong number of elements in annotation");
|
||||
}
|
||||
if (!urls[0].equals(codebase1)) {
|
||||
System.err.println("First URL in annotation is incorrect:");
|
||||
dumpURL(urls[0]);
|
||||
throw new RuntimeException(
|
||||
"first URL in annotation is incorrect");
|
||||
}
|
||||
if (!urls[1].equals(codebase2)) {
|
||||
System.err.println("Second URL in annotation is incorrect:");
|
||||
dumpURL(urls[1]);
|
||||
throw new RuntimeException(
|
||||
"second URL in annotation is incorrect");
|
||||
}
|
||||
|
||||
System.err.println("TEST PASSED: annotation matched codebase");
|
||||
} catch (Exception e) {
|
||||
TestLibrary.bomb(e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private static URL[] pathToURLs(String path)
|
||||
throws MalformedURLException
|
||||
{
|
||||
StringTokenizer st = new StringTokenizer(path); // divide by spaces
|
||||
URL[] urls = new URL[st.countTokens()];
|
||||
for (int i = 0; st.hasMoreTokens(); i++) {
|
||||
urls[i] = new URL(st.nextToken());
|
||||
}
|
||||
return urls;
|
||||
}
|
||||
|
||||
private static void dumpURL(URL u) {
|
||||
System.err.println("\tprotocol: " + u.getProtocol());
|
||||
System.err.println("\tauthority: " + u.getAuthority());
|
||||
System.err.println("\tuser info: " + u.getUserInfo());
|
||||
System.err.println("\thost: " + u.getHost());
|
||||
System.err.println("\tport: " + u.getPort());
|
||||
System.err.println("\tpath: " + u.getPath());
|
||||
System.err.println("\tfile: " + u.getFile());
|
||||
System.err.println("\tquery: " + u.getQuery());
|
||||
System.err.println("\tref: " + u.getRef());
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,234 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2008, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.rmi.server.*;
|
||||
import java.net.*;
|
||||
|
||||
public class Compress {
|
||||
|
||||
interface CompressConstants {
|
||||
// constants for 6-bit code values
|
||||
static final int NOP = 0; // no operation: used to pad words on flush()
|
||||
static final int RAW = 1; // introduces raw byte format
|
||||
static final int BASE = 2; // base for codes found in lookup table
|
||||
static final String codeTable =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ,.!?\"'()";
|
||||
}
|
||||
|
||||
public static class CompressRMIClientSocketFactory
|
||||
implements java.rmi.server.RMIClientSocketFactory, Serializable {
|
||||
|
||||
public Socket createSocket(String host, int port)
|
||||
throws IOException {
|
||||
|
||||
return ((Socket) new CompressSocket(host, port));
|
||||
}
|
||||
}
|
||||
|
||||
public static class CompressRMIServerSocketFactory
|
||||
implements RMIServerSocketFactory,
|
||||
Serializable {
|
||||
|
||||
public ServerSocket createServerSocket(int port)
|
||||
throws IOException {
|
||||
|
||||
return ((ServerSocket) new CompressServerSocket(port));
|
||||
}
|
||||
}
|
||||
|
||||
public static class CompressSocket extends Socket {
|
||||
private InputStream in;
|
||||
private OutputStream out;
|
||||
public CompressSocket() { super(); }
|
||||
public CompressSocket(String host, int port) throws IOException {
|
||||
super(host, port);
|
||||
}
|
||||
public InputStream getInputStream() throws IOException {
|
||||
if (in == null) {
|
||||
in = new CompressInputStream(super.getInputStream());
|
||||
}
|
||||
return in;
|
||||
}
|
||||
public OutputStream getOutputStream() throws IOException {
|
||||
if (out == null) {
|
||||
out = new CompressOutputStream(super.getOutputStream());
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
public static class CompressServerSocket extends ServerSocket {
|
||||
public CompressServerSocket(int port) throws IOException {
|
||||
super(port);
|
||||
}
|
||||
public Socket accept() throws IOException {
|
||||
Socket s = new CompressSocket();
|
||||
implAccept(s);
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
public static class CompressInputStream extends FilterInputStream
|
||||
implements CompressConstants
|
||||
{
|
||||
|
||||
public CompressInputStream(InputStream in) {
|
||||
super(in);
|
||||
}
|
||||
|
||||
// buffer of unpacked 6-bit codes from last 32-word read
|
||||
int buf[] = new int[5];
|
||||
|
||||
// position of next code to read in buffer (5 == end of buffer)
|
||||
int bufPos = 5;
|
||||
|
||||
public int read() throws IOException {
|
||||
try {
|
||||
int code;
|
||||
do {
|
||||
code = readCode();
|
||||
} while (code == NOP); // ignore NOP codes
|
||||
|
||||
if (code >= BASE)
|
||||
return codeTable.charAt(code - BASE);
|
||||
else if (code == RAW) {
|
||||
int high = readCode();
|
||||
int low = readCode();
|
||||
return (high << 4) | low;
|
||||
} else
|
||||
throw new IOException("unknown compression code: " + code);
|
||||
} catch (EOFException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int read(byte b[], int off, int len) throws IOException {
|
||||
if (len <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int c = read();
|
||||
if (c == -1) {
|
||||
return -1;
|
||||
}
|
||||
b[off] = (byte)c;
|
||||
|
||||
int i = 1;
|
||||
/*****
|
||||
try {
|
||||
for (; i < len ; i++) {
|
||||
c = read();
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
if (b != null) {
|
||||
b[off + i] = (byte)c;
|
||||
}
|
||||
}
|
||||
} catch (IOException ee) {
|
||||
}
|
||||
*****/
|
||||
return i;
|
||||
}
|
||||
|
||||
private int readCode() throws IOException {
|
||||
if (bufPos == 5) {
|
||||
int b1 = in.read();
|
||||
int b2 = in.read();
|
||||
int b3 = in.read();
|
||||
int b4 = in.read();
|
||||
if ((b1 | b2 | b3 | b4) < 0)
|
||||
throw new EOFException();
|
||||
int pack = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
|
||||
buf[0] = (pack >>> 24) & 0x3F;
|
||||
buf[1] = (pack >>> 18) & 0x3F;
|
||||
buf[2] = (pack >>> 12) & 0x3F;
|
||||
buf[3] = (pack >>> 6) & 0x3F;
|
||||
buf[4] = (pack >>> 0) & 0x3F;
|
||||
bufPos = 0;
|
||||
}
|
||||
return buf[bufPos++];
|
||||
}
|
||||
}
|
||||
|
||||
public static class CompressOutputStream extends FilterOutputStream
|
||||
implements CompressConstants
|
||||
{
|
||||
|
||||
public CompressOutputStream(OutputStream out) {
|
||||
super(out);
|
||||
}
|
||||
|
||||
// buffer of 6-bit codes to pack into next 32-bit word
|
||||
int buf[] = new int[5];
|
||||
|
||||
// number of valid codes pending in buffer
|
||||
int bufPos = 0;
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
b &= 0xFF; // force argument to a byte
|
||||
|
||||
int pos = codeTable.indexOf((char)b);
|
||||
if (pos != -1)
|
||||
writeCode(BASE + pos);
|
||||
else {
|
||||
writeCode(RAW);
|
||||
writeCode(b >> 4);
|
||||
writeCode(b & 0xF);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(byte b[], int off, int len) throws IOException {
|
||||
/*
|
||||
* This is quite an inefficient implementation, because it has to
|
||||
* call the other write method for every byte in the array. It
|
||||
* could be optimized for performance by doing all the processing
|
||||
* in this method.
|
||||
*/
|
||||
for (int i = 0; i < len; i++)
|
||||
write(b[off + i]);
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
while (bufPos > 0)
|
||||
writeCode(NOP);
|
||||
}
|
||||
|
||||
private void writeCode(int c) throws IOException {
|
||||
buf[bufPos++] = c;
|
||||
if (bufPos == 5) { // write next word when we have 5 codes
|
||||
int pack = (buf[0] << 24) | (buf[1] << 18) | (buf[2] << 12) |
|
||||
(buf[3] << 6) | buf[4];
|
||||
out.write((pack >>> 24) & 0xFF);
|
||||
out.write((pack >>> 16) & 0xFF);
|
||||
out.write((pack >>> 8) & 0xFF);
|
||||
out.write((pack >>> 0) & 0xFF);
|
||||
bufPos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2008, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
import java.rmi.*;
|
||||
import java.rmi.server.*;
|
||||
|
||||
interface Hello extends Remote {
|
||||
String sayHello() throws RemoteException;
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
import java.rmi.*;
|
||||
import java.rmi.server.*;
|
||||
import java.rmi.registry.*;
|
||||
|
||||
public class HelloImpl
|
||||
extends UnicastRemoteObject
|
||||
implements Hello
|
||||
{
|
||||
|
||||
public static boolean clientCalledSuccessfully = false;
|
||||
|
||||
public HelloImpl() throws RemoteException {
|
||||
super(0);
|
||||
}
|
||||
|
||||
public synchronized String sayHello() {
|
||||
HelloImpl.clientCalledSuccessfully = true;
|
||||
System.out.println("hello method called");
|
||||
this.notifyAll();
|
||||
return "hello";
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
/*
|
||||
* The following line is required with the JDK 1.2 VM so that the
|
||||
* VM can exit gracefully when this test completes. Otherwise, the
|
||||
* conservative garbage collector will find a handle to the server
|
||||
* object on the native stack and not clear the weak reference to
|
||||
* it in the RMI runtime's object table.
|
||||
*/
|
||||
Object dummy = new Object();
|
||||
Hello hello = null;
|
||||
Registry registry = null;
|
||||
|
||||
try {
|
||||
String protocol = "";
|
||||
if (args.length >= 1)
|
||||
protocol = args[0];
|
||||
|
||||
int registryPort = Integer.parseInt(System.getProperty("rmi.registry.port"));
|
||||
registry = java.rmi.registry.LocateRegistry.
|
||||
getRegistry("localhost", registryPort,
|
||||
new Compress.CompressRMIClientSocketFactory());
|
||||
UseCustomSocketFactory.checkStub(registry, "RMIClientSocket");
|
||||
hello = (Hello) registry.lookup("/HelloServer");
|
||||
|
||||
/* lookup server */
|
||||
System.err.println(hello.sayHello() +
|
||||
", remote greeting.");
|
||||
} catch (Exception e) {
|
||||
System.err.println("EXCEPTION OCCURRED:");
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
hello = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2008, 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.
|
||||
*/
|
||||
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class HelloImpl_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements Hello, java.rmi.Remote
|
||||
{
|
||||
private static java.rmi.server.Operation[] operations = {
|
||||
new java.rmi.server.Operation("java.lang.String sayHello()")
|
||||
};
|
||||
|
||||
private static final long interfaceHash = 6486744599627128933L;
|
||||
|
||||
private static final long serialVersionUID = 2;
|
||||
|
||||
private static boolean useNewInvoke;
|
||||
private static java.lang.reflect.Method $method_sayHello_0;
|
||||
|
||||
static {
|
||||
try {
|
||||
java.rmi.server.RemoteRef.class.getMethod("invoke",
|
||||
new java.lang.Class[] {
|
||||
java.rmi.Remote.class,
|
||||
java.lang.reflect.Method.class,
|
||||
java.lang.Object[].class,
|
||||
long.class
|
||||
});
|
||||
useNewInvoke = true;
|
||||
$method_sayHello_0 = Hello.class.getMethod("sayHello", new java.lang.Class[] {});
|
||||
} catch (java.lang.NoSuchMethodException e) {
|
||||
useNewInvoke = false;
|
||||
}
|
||||
}
|
||||
|
||||
// constructors
|
||||
public HelloImpl_Stub() {
|
||||
super();
|
||||
}
|
||||
public HelloImpl_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
// methods from remote interfaces
|
||||
|
||||
// implementation of sayHello()
|
||||
public java.lang.String sayHello()
|
||||
throws java.rmi.RemoteException
|
||||
{
|
||||
try {
|
||||
if (useNewInvoke) {
|
||||
Object $result = ref.invoke(this, $method_sayHello_0, null, 6043973830760146143L);
|
||||
return ((java.lang.String) $result);
|
||||
} else {
|
||||
java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash);
|
||||
ref.invoke(call);
|
||||
java.lang.String $result;
|
||||
try {
|
||||
java.io.ObjectInput in = call.getInputStream();
|
||||
$result = (java.lang.String) in.readObject();
|
||||
} catch (java.io.IOException e) {
|
||||
throw new java.rmi.UnmarshalException("error unmarshalling return", e);
|
||||
} catch (java.lang.ClassNotFoundException e) {
|
||||
throw new java.rmi.UnmarshalException("error unmarshalling return", e);
|
||||
} finally {
|
||||
ref.done(call);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.rmi.RemoteException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2024, 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 4148850
|
||||
*
|
||||
* @summary synopsis: need to obtain remote references securely
|
||||
*
|
||||
* @author Laird Dornin; code borrowed from Ann Wollrath
|
||||
*
|
||||
* @library ../../../../testlibrary
|
||||
* @modules java.rmi/sun.rmi.registry
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary Compress Hello HelloImpl HelloImpl_Stub
|
||||
* @run main/othervm/timeout=240 UseCustomSocketFactory
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.rmi.*;
|
||||
import java.rmi.server.*;
|
||||
import java.rmi.registry.*;
|
||||
|
||||
/**
|
||||
* Test ensures that the rmiregistry is capable of running over customx
|
||||
* (i.e. compression) client and server socket factories.
|
||||
*/
|
||||
public class UseCustomSocketFactory {
|
||||
|
||||
Hello hello = null;
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
Registry registry = null;
|
||||
HelloImpl impl = null;
|
||||
|
||||
System.out.println("\nRegression test for bug 4148850\n");
|
||||
|
||||
int registryPort = -1;
|
||||
|
||||
try {
|
||||
impl = new HelloImpl();
|
||||
|
||||
/* Make sure that the rmiregistry can communicate over a
|
||||
* custom socket. Ensure that the functionality exists to
|
||||
* allow the rmiregistry to be secure.
|
||||
*/
|
||||
registry = LocateRegistry.
|
||||
createRegistry(0,
|
||||
new Compress.CompressRMIClientSocketFactory(),
|
||||
new Compress.CompressRMIServerSocketFactory());
|
||||
registryPort = TestLibrary.getRegistryPort(registry);
|
||||
registry.rebind("/HelloServer", impl);
|
||||
checkStub(registry, "RMIServerSocket");
|
||||
|
||||
} catch (Exception e) {
|
||||
TestLibrary.bomb("creating registry", e);
|
||||
}
|
||||
|
||||
JavaVM serverVM = new JavaVM("HelloImpl",
|
||||
" -Drmi.registry.port=" +
|
||||
registryPort,
|
||||
"");
|
||||
|
||||
try {
|
||||
|
||||
/*
|
||||
* spawn VM for HelloServer which will download a client socket
|
||||
* factory
|
||||
*/
|
||||
serverVM.start();
|
||||
|
||||
synchronized (impl) {
|
||||
|
||||
System.out.println("waiting for remote notification");
|
||||
|
||||
if (!HelloImpl.clientCalledSuccessfully) {
|
||||
impl.wait(75 * 1000);
|
||||
}
|
||||
|
||||
if (!HelloImpl.clientCalledSuccessfully) {
|
||||
throw new RuntimeException("Client did not execute call in time...");
|
||||
}
|
||||
}
|
||||
|
||||
System.err.println("\nRegression test for bug 4148850 passed.\n ");
|
||||
|
||||
} catch (Exception e) {
|
||||
TestLibrary.bomb("test failed", e);
|
||||
|
||||
} finally {
|
||||
serverVM.destroy();
|
||||
try {
|
||||
registry.unbind("/HelloServer");
|
||||
} catch (Exception e) {
|
||||
TestLibrary.bomb("unbinding HelloServer", e);
|
||||
}
|
||||
TestLibrary.unexport(registry);
|
||||
TestLibrary.unexport(impl);
|
||||
impl = null;
|
||||
registry = null;
|
||||
}
|
||||
}
|
||||
|
||||
static void checkStub(Object stub, String toCheck) throws RemoteException {
|
||||
System.err.println("Ensuring that the stub contains a socket factory string: " +
|
||||
toCheck);
|
||||
System.err.println(stub);
|
||||
if (stub.toString().indexOf(toCheck) < 0) {
|
||||
throw new RemoteException("RemoteStub.toString() did not contain instance of "
|
||||
+ toCheck);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2008, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
interface CompressConstants {
|
||||
|
||||
// constants for 6-bit code values
|
||||
static final int NOP = 0; // no operation: used to pad words on flush()
|
||||
static final int RAW = 1; // introduces raw byte format
|
||||
static final int BASE = 2; // base for codes found in lookup table
|
||||
static final String codeTable =
|
||||
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ,.!?\"'()";
|
||||
}
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2008, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
|
||||
class CompressInputStream extends FilterInputStream
|
||||
implements CompressConstants
|
||||
{
|
||||
|
||||
public CompressInputStream(InputStream in) {
|
||||
super(in);
|
||||
}
|
||||
|
||||
// buffer of unpacked 6-bit codes from last 32-word read
|
||||
int buf[] = new int[5];
|
||||
|
||||
// position of next code to read in buffer (5 == end of buffer)
|
||||
int bufPos = 5;
|
||||
|
||||
public int read() throws IOException {
|
||||
try {
|
||||
int code;
|
||||
do {
|
||||
code = readCode();
|
||||
} while (code == NOP); // ignore NOP codes
|
||||
|
||||
if (code >= BASE)
|
||||
return codeTable.charAt(code - BASE);
|
||||
else if (code == RAW) {
|
||||
int high = readCode();
|
||||
int low = readCode();
|
||||
return (high << 4) | low;
|
||||
} else
|
||||
throw new IOException("unknown compression code: " + code);
|
||||
} catch (EOFException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int read(byte b[], int off, int len) throws IOException {
|
||||
if (len <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int c = read();
|
||||
if (c == -1) {
|
||||
return -1;
|
||||
}
|
||||
b[off] = (byte)c;
|
||||
|
||||
int i = 1;
|
||||
/*****
|
||||
try {
|
||||
for (; i < len ; i++) {
|
||||
c = read();
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
if (b != null) {
|
||||
b[off + i] = (byte)c;
|
||||
}
|
||||
}
|
||||
} catch (IOException ee) {
|
||||
}
|
||||
*****/
|
||||
return i;
|
||||
}
|
||||
|
||||
private int readCode() throws IOException {
|
||||
if (bufPos == 5) {
|
||||
int b1 = in.read();
|
||||
int b2 = in.read();
|
||||
int b3 = in.read();
|
||||
int b4 = in.read();
|
||||
if ((b1 | b2 | b3 | b4) < 0)
|
||||
throw new EOFException();
|
||||
int pack = (b1 << 24) | (b2 << 16) | (b3 << 8) | b4;
|
||||
buf[0] = (pack >>> 24) & 0x3F;
|
||||
buf[1] = (pack >>> 18) & 0x3F;
|
||||
buf[2] = (pack >>> 12) & 0x3F;
|
||||
buf[3] = (pack >>> 6) & 0x3F;
|
||||
buf[4] = (pack >>> 0) & 0x3F;
|
||||
bufPos = 0;
|
||||
}
|
||||
return buf[bufPos++];
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2008, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
|
||||
class CompressOutputStream extends FilterOutputStream
|
||||
implements CompressConstants
|
||||
{
|
||||
|
||||
public CompressOutputStream(OutputStream out) {
|
||||
super(out);
|
||||
}
|
||||
|
||||
// buffer of 6-bit codes to pack into next 32-bit word
|
||||
int buf[] = new int[5];
|
||||
|
||||
// number of valid codes pending in buffer
|
||||
int bufPos = 0;
|
||||
|
||||
public void write(int b) throws IOException {
|
||||
b &= 0xFF; // force argument to a byte
|
||||
|
||||
int pos = codeTable.indexOf((char)b);
|
||||
if (pos != -1)
|
||||
writeCode(BASE + pos);
|
||||
else {
|
||||
writeCode(RAW);
|
||||
writeCode(b >> 4);
|
||||
writeCode(b & 0xF);
|
||||
}
|
||||
}
|
||||
|
||||
public void write(byte b[], int off, int len) throws IOException {
|
||||
/*
|
||||
* This is quite an inefficient implementation, because it has to
|
||||
* call the other write method for every byte in the array. It
|
||||
* could be optimized for performance by doing all the processing
|
||||
* in this method.
|
||||
*/
|
||||
for (int i = 0; i < len; i++)
|
||||
write(b[off + i]);
|
||||
}
|
||||
|
||||
public void flush() throws IOException {
|
||||
while (bufPos > 0)
|
||||
writeCode(NOP);
|
||||
}
|
||||
|
||||
private void writeCode(int c) throws IOException {
|
||||
buf[bufPos++] = c;
|
||||
if (bufPos == 5) { // write next word when we have 5 codes
|
||||
int pack = (buf[0] << 24) | (buf[1] << 18) | (buf[2] << 12) |
|
||||
(buf[3] << 6) | buf[4];
|
||||
out.write((pack >>> 24) & 0xFF);
|
||||
out.write((pack >>> 16) & 0xFF);
|
||||
out.write((pack >>> 8) & 0xFF);
|
||||
out.write((pack >>> 0) & 0xFF);
|
||||
bufPos = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2008, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
import java.rmi.*;
|
||||
|
||||
public interface Echo extends Remote {
|
||||
|
||||
byte[] echoNot(byte[] data) throws RemoteException;
|
||||
}
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2024, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*/
|
||||
import java.rmi.*;
|
||||
import java.rmi.server.*;
|
||||
|
||||
public class EchoImpl
|
||||
extends UnicastRemoteObject
|
||||
implements Echo
|
||||
{
|
||||
private static final byte[] pattern = { (byte) 'A' };
|
||||
|
||||
public EchoImpl(String protocol) throws RemoteException {
|
||||
super(0,
|
||||
new MultiSocketFactory.ClientFactory(protocol, pattern),
|
||||
new MultiSocketFactory.ServerFactory(protocol, pattern));
|
||||
}
|
||||
|
||||
public byte[] echoNot(byte[] data) {
|
||||
byte[] result = new byte[data.length];
|
||||
for (int i = 0; i < data.length; i++)
|
||||
result[i] = (byte) ~data[i];
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
/*
|
||||
* The following line is required with the JDK 1.2 VM so that the
|
||||
* VM can exit gracefully when this test completes. Otherwise, the
|
||||
* conservative garbage collector will find a handle to the server
|
||||
* object on the native stack and not clear the weak reference to
|
||||
* it in the RMI runtime's object table.
|
||||
*/
|
||||
Object dummy = new Object();
|
||||
|
||||
try {
|
||||
String protocol = "";
|
||||
if (args.length >= 1)
|
||||
protocol = args[0];
|
||||
|
||||
System.out.println("EchoServer: creating remote object");
|
||||
EchoImpl impl = new EchoImpl(protocol);
|
||||
int registryPort = Integer.parseInt(System.getProperty("rmi.registry.port"));
|
||||
System.out.println("EchoServer: binding in registry");
|
||||
Naming.rebind("//:" + registryPort +
|
||||
"/EchoServer", impl);
|
||||
System.out.println("EchoServer ready.");
|
||||
} catch (Exception e) {
|
||||
System.err.println("EXCEPTION OCCURRED:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2008, 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.
|
||||
*/
|
||||
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class EchoImpl_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements Echo, java.rmi.Remote
|
||||
{
|
||||
private static final long serialVersionUID = 2;
|
||||
|
||||
private static java.lang.reflect.Method $method_echoNot_0;
|
||||
|
||||
static {
|
||||
try {
|
||||
$method_echoNot_0 = Echo.class.getMethod("echoNot", new java.lang.Class[] {byte[].class});
|
||||
} catch (java.lang.NoSuchMethodException e) {
|
||||
throw new java.lang.NoSuchMethodError(
|
||||
"stub class initialization failed");
|
||||
}
|
||||
}
|
||||
|
||||
// constructors
|
||||
public EchoImpl_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
// methods from remote interfaces
|
||||
|
||||
// implementation of echoNot(byte[])
|
||||
public byte[] echoNot(byte[] $param_arrayOf_byte_1)
|
||||
throws java.rmi.RemoteException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_echoNot_0, new java.lang.Object[] {$param_arrayOf_byte_1}, -4295721514897591756L);
|
||||
return ((byte[]) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.rmi.RemoteException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,226 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2008, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.rmi.*;
|
||||
import java.rmi.server.*;
|
||||
import java.util.zip.*;
|
||||
|
||||
|
||||
public class MultiSocketFactory {
|
||||
|
||||
private static RMISocketFactory def =
|
||||
RMISocketFactory.getDefaultSocketFactory();
|
||||
|
||||
|
||||
public static class ServerFactory
|
||||
implements RMIServerSocketFactory, Serializable
|
||||
{
|
||||
|
||||
private String protocol;
|
||||
private byte[] data;
|
||||
|
||||
public ServerFactory(String protocol, byte[] data) {
|
||||
this.protocol = protocol;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public ServerSocket createServerSocket(int port) throws IOException
|
||||
{
|
||||
if (protocol.equals("compress")) {
|
||||
return new CompressServerSocket(port);
|
||||
|
||||
} else if (protocol.equals("xor")) {
|
||||
if (data == null || data.length != 1)
|
||||
throw new IOException("invalid argument for XOR protocol");
|
||||
return new XorServerSocket(port, data[0]);
|
||||
|
||||
}
|
||||
|
||||
return def.createServerSocket(port);
|
||||
}
|
||||
}
|
||||
|
||||
public static class ClientFactory
|
||||
implements RMIClientSocketFactory, Serializable
|
||||
{
|
||||
|
||||
private String protocol;
|
||||
private byte[] data;
|
||||
|
||||
public ClientFactory(String protocol, byte[] data) {
|
||||
this.protocol = protocol;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public Socket createSocket(String host, int port)
|
||||
throws IOException
|
||||
{
|
||||
if (protocol.equals("compress")) {
|
||||
return new CompressSocket(host, port);
|
||||
|
||||
} else if (protocol.equals("xor")) {
|
||||
if (data == null || data.length != 1)
|
||||
throw new IOException("invalid argument for XOR protocol");
|
||||
return new XorSocket(host, port, data[0]);
|
||||
|
||||
}
|
||||
|
||||
return def.createSocket(host, port);
|
||||
}
|
||||
}
|
||||
|
||||
static class CompressSocket extends Socket {
|
||||
private InputStream in;
|
||||
private OutputStream out;
|
||||
public CompressSocket() { super(); }
|
||||
public CompressSocket(String host, int port) throws IOException {
|
||||
super(host, port);
|
||||
}
|
||||
public InputStream getInputStream() throws IOException {
|
||||
if (in == null) {
|
||||
in = new CompressInputStream(super.getInputStream());
|
||||
}
|
||||
return in;
|
||||
}
|
||||
public OutputStream getOutputStream() throws IOException {
|
||||
if (out == null) {
|
||||
out = new CompressOutputStream(super.getOutputStream());
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
static class CompressServerSocket extends ServerSocket {
|
||||
public CompressServerSocket(int port) throws IOException {
|
||||
super(port);
|
||||
}
|
||||
public Socket accept() throws IOException {
|
||||
Socket s = new CompressSocket();
|
||||
implAccept(s);
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
static class XorSocket extends Socket {
|
||||
private byte pattern;
|
||||
private InputStream in;
|
||||
private OutputStream out;
|
||||
public XorSocket(byte pattern) { super(); this.pattern = pattern; }
|
||||
public XorSocket(String host, int port, byte pattern)
|
||||
throws IOException
|
||||
{
|
||||
super(host, port);
|
||||
this.pattern = pattern;
|
||||
}
|
||||
public InputStream getInputStream() throws IOException {
|
||||
if (in == null) {
|
||||
in = new XorInputStream(super.getInputStream(), pattern);
|
||||
}
|
||||
return in;
|
||||
}
|
||||
public OutputStream getOutputStream() throws IOException {
|
||||
if (out == null) {
|
||||
out = new XorOutputStream(super.getOutputStream(), pattern);
|
||||
}
|
||||
return out;
|
||||
}
|
||||
}
|
||||
|
||||
static class XorServerSocket extends ServerSocket {
|
||||
private byte pattern;
|
||||
public XorServerSocket(int port, byte pattern) throws IOException {
|
||||
super(port);
|
||||
this.pattern = pattern;
|
||||
}
|
||||
public Socket accept() throws IOException {
|
||||
Socket s = new XorSocket(pattern);
|
||||
implAccept(s);
|
||||
return s;
|
||||
}
|
||||
}
|
||||
|
||||
static class XorOutputStream extends FilterOutputStream {
|
||||
private byte pattern;
|
||||
public XorOutputStream(OutputStream out, byte pattern) {
|
||||
super(out);
|
||||
this.pattern = pattern;
|
||||
}
|
||||
public void write(int b) throws IOException {
|
||||
out.write(b ^ pattern);
|
||||
out.flush();
|
||||
}
|
||||
public void write(byte b[], int off, int len) throws IOException {
|
||||
for (int i = 0; i < len; i++)
|
||||
write(b[off + i]);
|
||||
}
|
||||
}
|
||||
|
||||
static class XorInputStream extends FilterInputStream {
|
||||
private byte pattern;
|
||||
public XorInputStream(InputStream in, byte pattern) {
|
||||
super(in);
|
||||
this.pattern = pattern;
|
||||
}
|
||||
public int read() throws IOException {
|
||||
int b = in.read();
|
||||
// System.out.print("BEFORE: " + Integer.toHexString(b));
|
||||
if (b != -1)
|
||||
b = (b ^ pattern) & 0xFF;
|
||||
// System.out.println("\tAFTER: " + Integer.toHexString(b));
|
||||
return b;
|
||||
}
|
||||
public int read(byte b[], int off, int len) throws IOException {
|
||||
if (len <= 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int c = read();
|
||||
if (c == -1) {
|
||||
return -1;
|
||||
}
|
||||
b[off] = (byte)c;
|
||||
|
||||
int i = 1;
|
||||
/*****
|
||||
try {
|
||||
for (; i < len ; i++) {
|
||||
c = read();
|
||||
if (c == -1) {
|
||||
break;
|
||||
}
|
||||
if (b != null) {
|
||||
b[off + i] = (byte)c;
|
||||
}
|
||||
}
|
||||
} catch (IOException ee) {
|
||||
}
|
||||
*****/
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* Copyright (c) 2020, 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.
|
||||
*/
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.net.Socket;
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.server.RMIClientSocketFactory;
|
||||
import java.rmi.server.RMISocketFactory;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
|
||||
/* @test
|
||||
* @bug 8237368
|
||||
* @summary Allow custom socket factory to be null in TCPEndpoint.
|
||||
* @run main/othervm TCPEndpointReadBug
|
||||
*/
|
||||
public class TCPEndpointReadBug {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
final I implC = new C();
|
||||
final I remoteC = (I)UnicastRemoteObject.exportObject(
|
||||
implC, 0, new CSF(), RMISocketFactory.getDefaultSocketFactory());
|
||||
|
||||
// Pass a remote object with a custom socket factory as an argument
|
||||
remoteC.echo(remoteC);
|
||||
|
||||
// Pass nothing and get an object with a custom socket factory in return
|
||||
remoteC.echo(null);
|
||||
}
|
||||
|
||||
interface I extends Remote {
|
||||
I echo(I intf) throws RemoteException;
|
||||
}
|
||||
|
||||
static class C implements I {
|
||||
@Override
|
||||
public I echo(I intf) {
|
||||
try {
|
||||
return (I)UnicastRemoteObject
|
||||
.exportObject(new C(),0, new CSF(), RMISocketFactory.getDefaultSocketFactory());
|
||||
} catch (RemoteException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A configurable socket factory in which for test purposes supplies null.
|
||||
*/
|
||||
static class CSF implements Serializable, RMIClientSocketFactory {
|
||||
private static final long serialVersionUID = 1;
|
||||
|
||||
@Override
|
||||
public boolean equals(Object object) {
|
||||
return object instanceof CSF;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return 424242;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Socket createSocket(String host, int port)
|
||||
throws IOException {
|
||||
|
||||
final RMIClientSocketFactory defaultFactory =
|
||||
RMISocketFactory.getDefaultSocketFactory();
|
||||
return defaultFactory.createSocket(host, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Use writeReplace to use a different client socket factory. In the
|
||||
* problematic case, the replacement is null.
|
||||
*/
|
||||
private Object writeReplace() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instances of this class should never be deserialized because they
|
||||
* are always replaced during serialization.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
private void readObject(ObjectInputStream in) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2024, 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 4127826
|
||||
*
|
||||
* @summary synopsis: need to download factories for use with custom socket
|
||||
* types
|
||||
* @author Ann Wollrath
|
||||
*
|
||||
* @library ../../../../testlibrary
|
||||
* @modules java.rmi/sun.rmi.registry
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary JavaVM Echo EchoImpl EchoImpl_Stub
|
||||
* @run main/othervm/timeout=120 UseCustomSocketFactory
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.rmi.*;
|
||||
import java.rmi.registry.*;
|
||||
|
||||
public class UseCustomSocketFactory {
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
int registryPort = -1;
|
||||
|
||||
String[] protocols = new String[] { "", "compress", "xor" };
|
||||
|
||||
System.out.println("\nRegression test for bug 4127826\n");
|
||||
|
||||
try {
|
||||
Registry registry = TestLibrary.createRegistryOnEphemeralPort();
|
||||
registryPort = TestLibrary.getRegistryPort(registry);
|
||||
} catch (RemoteException e) {
|
||||
TestLibrary.bomb("creating registry", e);
|
||||
}
|
||||
for (String protocol : protocols) {
|
||||
JavaVM serverVM = new JavaVM("EchoImpl",
|
||||
" -Drmi.registry.port=" +
|
||||
registryPort, protocol);
|
||||
System.err.println("\nusing protocol: " +
|
||||
("".equals(protocol) ? "none" : protocol));
|
||||
try {
|
||||
/* spawn VM for EchoServer */
|
||||
serverVM.start();
|
||||
|
||||
/* lookup server */
|
||||
Echo obj = null;
|
||||
// 16 seconds timeout
|
||||
long stopTime = System.currentTimeMillis() + 16000;
|
||||
do {
|
||||
try {
|
||||
obj = (Echo) Naming.lookup("//:" + registryPort +
|
||||
"/EchoServer");
|
||||
break;
|
||||
} catch (NotBoundException e) {
|
||||
try {
|
||||
Thread.sleep(200);
|
||||
} catch (InterruptedException ignore) {
|
||||
}
|
||||
}
|
||||
} while (System.currentTimeMillis() < stopTime);
|
||||
|
||||
if (obj == null)
|
||||
TestLibrary.bomb("server not bound in 8 tries", null);
|
||||
|
||||
/* invoke remote method and print result*/
|
||||
System.err.println("Bound to " + obj);
|
||||
byte[] data = ("Greetings, citizen " +
|
||||
System.getProperty("user.name") + "!"). getBytes();
|
||||
byte[] result = obj.echoNot(data);
|
||||
for (int j = 0; j < result.length; j++)
|
||||
result[j] = (byte) ~result[j];
|
||||
System.err.println("Result: " + new String(result));
|
||||
|
||||
} catch (IOException e) {
|
||||
TestLibrary.bomb("test failed", e);
|
||||
|
||||
} finally {
|
||||
serverVM.destroy();
|
||||
try {
|
||||
Naming.unbind("//:" + registryPort +
|
||||
"/EchoServer");
|
||||
} catch (RemoteException | NotBoundException | MalformedURLException e) {
|
||||
TestLibrary.bomb("unbinding EchoServer", e);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2014, 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 4099660 4102938
|
||||
* @summary Remote classes not extending RemoteObject should be able to
|
||||
* implement hashCode() and equals() methods so that instances
|
||||
* can be successfully compared to RemoteObject instances
|
||||
* (specifically: stubs) that contain the instance's RemoteRef.
|
||||
* @author Peter Jones
|
||||
*
|
||||
* @build NotExtending_Stub NotExtending_Skel
|
||||
* @run main/othervm NotExtending
|
||||
*/
|
||||
|
||||
|
||||
import java.rmi.*;
|
||||
import java.rmi.server.*;
|
||||
|
||||
public class NotExtending implements Remote {
|
||||
|
||||
/** remote stub for this server instance */
|
||||
private Remote stub;
|
||||
/** value of stub's hash code */
|
||||
private int hashValue;
|
||||
/** true if the hashValue field has been initialized */
|
||||
private boolean hashValueInitialized = false;
|
||||
|
||||
// no declared constructor - rely on implicit no-arg contructor
|
||||
|
||||
public Remote export() throws RemoteException {
|
||||
stub = UnicastRemoteObject.exportObject(this);
|
||||
setHashValue(stub.hashCode());
|
||||
return stub;
|
||||
}
|
||||
|
||||
public void unexport() throws RemoteException {
|
||||
UnicastRemoteObject.unexportObject(this, true);
|
||||
}
|
||||
|
||||
private void setHashValue(int value) {
|
||||
hashValue = value;
|
||||
hashValueInitialized = true;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
/*
|
||||
* Test fails if the hashCode() method is called (during export)
|
||||
* before the correct hash value has been initialized.
|
||||
*/
|
||||
if (!hashValueInitialized) {
|
||||
throw new AssertionError(
|
||||
"hashCode() invoked before hashValue initialized");
|
||||
}
|
||||
return hashValue;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
return stub.equals(obj);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
NotExtending server = null;
|
||||
|
||||
try {
|
||||
/*
|
||||
* Verify that hashCode() is not invoked before it is
|
||||
* initialized. Tests bugid 4102938.
|
||||
*/
|
||||
server = new NotExtending();
|
||||
Remote stub = server.export();
|
||||
System.err.println("Server exported without invoking hashCode().");
|
||||
|
||||
/*
|
||||
* Verify that passing stub to server's equals() method
|
||||
* returns true.
|
||||
*/
|
||||
if (server.equals(stub)) {
|
||||
System.err.println("server.equals(stub) returns true");
|
||||
} else {
|
||||
throw new AssertionError("server.equals(stub) returns false");
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that passing server to stub's equals() method
|
||||
* returns true. Tests bugid 4099660.
|
||||
*/
|
||||
if (stub.equals(server)) {
|
||||
System.err.println("stub.equals(server) returns true");
|
||||
} else {
|
||||
throw new AssertionError("stub.equals(server) returns false");
|
||||
}
|
||||
} finally {
|
||||
if (server != null) {
|
||||
server.unexport();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 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.
|
||||
*/
|
||||
|
||||
// Skeleton class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class NotExtending_Skel
|
||||
implements java.rmi.server.Skeleton
|
||||
{
|
||||
private static java.rmi.server.Operation[] operations = {
|
||||
|
||||
};
|
||||
|
||||
private static final long interfaceHash = 3103311997983563335L;
|
||||
|
||||
public java.rmi.server.Operation[] getOperations() {
|
||||
return operations;
|
||||
}
|
||||
|
||||
public void dispatch(java.rmi.Remote obj, java.rmi.server.RemoteCall call, int opnum, long hash)
|
||||
throws java.lang.Exception
|
||||
{
|
||||
if (opnum < 0) {
|
||||
throw new java.rmi.UnmarshalException("invalid method hash");
|
||||
} else {
|
||||
if (hash != interfaceHash)
|
||||
throw new java.rmi.server.SkeletonMismatchException("interface hash mismatch");
|
||||
}
|
||||
|
||||
NotExtending server = (NotExtending) obj;
|
||||
switch (opnum) {
|
||||
default:
|
||||
throw new java.rmi.UnmarshalException("invalid method number");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 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.
|
||||
*/
|
||||
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class NotExtending_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements java.rmi.Remote
|
||||
{
|
||||
private static java.rmi.server.Operation[] operations = {
|
||||
|
||||
};
|
||||
|
||||
private static final long interfaceHash = 3103311997983563335L;
|
||||
|
||||
private static final long serialVersionUID = 2;
|
||||
|
||||
private static boolean useNewInvoke;
|
||||
|
||||
static {
|
||||
try {
|
||||
java.rmi.server.RemoteRef.class.getMethod("invoke",
|
||||
new java.lang.Class[] {
|
||||
java.rmi.Remote.class,
|
||||
java.lang.reflect.Method.class,
|
||||
java.lang.Object[].class,
|
||||
long.class
|
||||
});
|
||||
useNewInvoke = true;
|
||||
} catch (java.lang.NoSuchMethodException e) {
|
||||
useNewInvoke = false;
|
||||
}
|
||||
}
|
||||
|
||||
// constructors
|
||||
public NotExtending_Stub() {
|
||||
super();
|
||||
}
|
||||
public NotExtending_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
// methods from remote interfaces
|
||||
}
|
||||
116
test/jdk/java/rmi/server/RemoteObject/toStub/ToStub.java
Normal file
116
test/jdk/java/rmi/server/RemoteObject/toStub/ToStub.java
Normal file
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2024, 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 4507539
|
||||
* @summary support using dynamic proxies as RMI stubs
|
||||
* @author Ann Wollrath
|
||||
*
|
||||
* @build ToStub ToStub_Stub
|
||||
* @run main/othervm/timeout=240 ToStub
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.rmi.NoSuchObjectException;
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.server.RemoteObjectInvocationHandler;
|
||||
import java.rmi.server.RemoteStub;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
import java.rmi.server.RemoteObject;
|
||||
|
||||
public class ToStub implements RemoteInterface {
|
||||
|
||||
|
||||
public Object passObject(Object obj) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
RemoteInterface server1 = null;
|
||||
RemoteInterface server2 = null;
|
||||
RemoteInterface stub = null;
|
||||
RemoteInterface proxy = null;
|
||||
|
||||
try {
|
||||
System.setProperty("java.rmi.server.ignoreStubClasses", "true");
|
||||
|
||||
System.err.println("export objects");
|
||||
server1 = new ToStub();
|
||||
server2 = new ToStub();
|
||||
stub = (RemoteInterface) UnicastRemoteObject.exportObject(server1);
|
||||
proxy = (RemoteInterface)
|
||||
UnicastRemoteObject.exportObject(server2, 0);
|
||||
|
||||
System.err.println("test toStub");
|
||||
if (stub != RemoteObject.toStub(server1)) {
|
||||
throw new RuntimeException(
|
||||
"toStub returned incorrect value for server1");
|
||||
}
|
||||
|
||||
if (!Proxy.isProxyClass(proxy.getClass())) {
|
||||
throw new RuntimeException("proxy is not a dynamic proxy");
|
||||
}
|
||||
|
||||
if (proxy != RemoteObject.toStub(server2)) {
|
||||
throw new RuntimeException(
|
||||
"toStub returned incorrect value for server2");
|
||||
}
|
||||
|
||||
try {
|
||||
RemoteObject.toStub(new ToStub());
|
||||
throw new RuntimeException(
|
||||
"stub returned for exported object!");
|
||||
} catch (NoSuchObjectException nsoe) {
|
||||
}
|
||||
|
||||
System.err.println("invoke methods");
|
||||
Object obj = stub.passObject(stub);
|
||||
if (!stub.equals(obj)) {
|
||||
throw new RuntimeException("returned stub not equal");
|
||||
}
|
||||
|
||||
obj = proxy.passObject(proxy);
|
||||
if (!proxy.equals(obj)) {
|
||||
throw new RuntimeException("returned proxy not equal");
|
||||
}
|
||||
|
||||
System.err.println("TEST PASSED");
|
||||
|
||||
} finally {
|
||||
if (stub != null) {
|
||||
UnicastRemoteObject.unexportObject(server1, true);
|
||||
}
|
||||
|
||||
if (proxy != null) {
|
||||
UnicastRemoteObject.unexportObject(server2, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface RemoteInterface extends Remote {
|
||||
Object passObject(Object obj) throws IOException;
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 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.
|
||||
*/
|
||||
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class ToStub_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements RemoteInterface
|
||||
{
|
||||
private static final long serialVersionUID = 2;
|
||||
|
||||
private static java.lang.reflect.Method $method_passObject_0;
|
||||
|
||||
static {
|
||||
try {
|
||||
$method_passObject_0 = RemoteInterface.class.getMethod("passObject", new java.lang.Class[] {java.lang.Object.class});
|
||||
} catch (java.lang.NoSuchMethodException e) {
|
||||
throw new java.lang.NoSuchMethodError(
|
||||
"stub class initialization failed");
|
||||
}
|
||||
}
|
||||
|
||||
// constructors
|
||||
public ToStub_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
// methods from remote interfaces
|
||||
|
||||
// implementation of passObject(Object)
|
||||
public java.lang.Object passObject(java.lang.Object $param_Object_1)
|
||||
throws java.io.IOException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_passObject_0, new java.lang.Object[] {$param_Object_1}, 3074202549763602823L);
|
||||
return ((java.lang.Object) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,136 @@
|
|||
/*
|
||||
* Copyright (c) 2021, 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 4460983
|
||||
* @summary This test verifies that when a RemoteObject is being
|
||||
* deserialized, if the "external ref type name" is a non-empty
|
||||
* string that is not equal to one of the external ref type names
|
||||
* required to be supported by the specification, then a
|
||||
* ClassNotFoundException is thrown. Of particular note, with the
|
||||
* specification change for 4460983, "ActivatableServerRef" is no
|
||||
* longer a supported "external ref type name", and the names of
|
||||
* other classes in the internal package sun.rmi.server should
|
||||
* produce the same result.
|
||||
* @author Peter Jones
|
||||
*
|
||||
* @run main/othervm UnrecognizedRefType
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutput;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.lang.reflect.Method;
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.server.Operation;
|
||||
import java.rmi.server.RemoteCall;
|
||||
import java.rmi.server.RemoteObject;
|
||||
import java.rmi.server.RemoteRef;
|
||||
|
||||
public class UnrecognizedRefType {
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.err.println("\nRegression test for bug 4460983\n");
|
||||
|
||||
test(new FakeRemoteObject("ActivatableServerRef"));
|
||||
test(new FakeRemoteObject("MarshalInputStream"));
|
||||
test(new FakeRemoteObject("XXX"));
|
||||
|
||||
System.err.println("TEST PASSED");
|
||||
}
|
||||
|
||||
private static void test(RemoteObject obj) throws Exception {
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
ObjectOutputStream out = new ObjectOutputStream(bout);
|
||||
out.writeObject(obj);
|
||||
ByteArrayInputStream bin =
|
||||
new ByteArrayInputStream(bout.toByteArray());
|
||||
ObjectInputStream in = new ObjectInputStream(bin);
|
||||
try {
|
||||
Object obj2 = in.readObject();
|
||||
System.err.println(
|
||||
"Object unexpectedly deserialized successfully: " + obj2);
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: object successfully deserialized");
|
||||
} catch (ClassNotFoundException e) {
|
||||
System.err.println("ClassNotFoundException as expected:");
|
||||
e.printStackTrace();
|
||||
} // other exceptions cause test failure
|
||||
}
|
||||
|
||||
private static class FakeRemoteObject extends RemoteObject {
|
||||
FakeRemoteObject(String refType) {
|
||||
super(new FakeRemoteRef(refType));
|
||||
}
|
||||
}
|
||||
|
||||
private static class FakeRemoteRef implements RemoteRef {
|
||||
private final String refType;
|
||||
|
||||
FakeRemoteRef(String refType) {
|
||||
this.refType = refType;
|
||||
}
|
||||
|
||||
public Object invoke(Remote obj,
|
||||
Method method,
|
||||
Object[] params,
|
||||
long opnum)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public RemoteCall newCall(RemoteObject obj,
|
||||
Operation[] op,
|
||||
int opnum,
|
||||
long hash)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void invoke(RemoteCall call) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void done(RemoteCall call) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public String getRefClass(java.io.ObjectOutput out) {
|
||||
return refType;
|
||||
}
|
||||
|
||||
public int remoteHashCode() { return hashCode(); }
|
||||
public boolean remoteEquals(RemoteRef obj) { return equals(obj); }
|
||||
public String remoteToString() { return toString(); }
|
||||
|
||||
public void readExternal(ObjectInput in) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void writeExternal(ObjectOutput out) {
|
||||
// no data to write
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,234 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2012, 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 4251010
|
||||
* @summary equals does not works on stub objects created with
|
||||
* custom socket AndFactory
|
||||
* @author Laird Dornin
|
||||
*
|
||||
* @library ../../../testlibrary
|
||||
* @modules java.rmi/sun.rmi.registry
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary
|
||||
* @run main/othervm/timeout=40 VerifyRemoteEquals
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.rmi.*;
|
||||
import java.rmi.server.*;
|
||||
|
||||
/**
|
||||
* Test ensures that a stub that has never been serialized and one
|
||||
* that has can be .equals(). Test also ensures that stubs with
|
||||
* custom socket factories can be .equals() with equivalent stubs.
|
||||
*/
|
||||
public class VerifyRemoteEquals {
|
||||
|
||||
/**
|
||||
* Remote interface.
|
||||
*/
|
||||
public interface Test extends Remote {
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of Remote interface passing custom socket
|
||||
* factories
|
||||
*/
|
||||
public static final class TestImpl
|
||||
extends UnicastRemoteObject implements Test
|
||||
{
|
||||
public TestImpl() throws RemoteException {
|
||||
super();
|
||||
}
|
||||
|
||||
public TestImpl(RMIClientSocketFactory clientFactory,
|
||||
RMIServerSocketFactory serverFactory)
|
||||
throws RemoteException
|
||||
{
|
||||
|
||||
super(0, clientFactory, serverFactory);
|
||||
}
|
||||
|
||||
public TestImpl(RMISocketFactory factory)
|
||||
throws RemoteException
|
||||
{
|
||||
super(0, factory, factory);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remote interface for retrieving Test object.
|
||||
*/
|
||||
public interface TestHome extends Remote {
|
||||
public Test get() throws RemoteException;
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of interface TestHome.
|
||||
*/
|
||||
public static final class TestHomeImpl
|
||||
extends UnicastRemoteObject implements TestHome
|
||||
{
|
||||
private Test test;
|
||||
|
||||
public TestHomeImpl(Test test)
|
||||
throws RemoteException {
|
||||
|
||||
super();
|
||||
|
||||
this.test = test;
|
||||
}
|
||||
|
||||
public Test get() {
|
||||
return test;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom server socket factory.
|
||||
*/
|
||||
public static final class ServerSocketAndFactory
|
||||
extends ServerSocket implements RMIServerSocketFactory, Serializable
|
||||
{
|
||||
ServerSocketAndFactory() throws IOException, java.net.UnknownHostException {
|
||||
// I am forced to do something useless with the parent
|
||||
// constructor
|
||||
super(0);
|
||||
}
|
||||
ServerSocketAndFactory(int port) throws IOException,
|
||||
java.net.UnknownHostException
|
||||
{
|
||||
super(port);
|
||||
}
|
||||
|
||||
public ServerSocket createServerSocket(int port)
|
||||
throws IOException
|
||||
{
|
||||
|
||||
return new ServerSocketAndFactory(port);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return getLocalPort();
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof ServerSocketAndFactory) {
|
||||
ServerSocketAndFactory ssf = (ServerSocketAndFactory) obj;
|
||||
if (getLocalPort() == ssf.getLocalPort()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom socket factory.
|
||||
*/
|
||||
public static final class ClientSocketAndFactory
|
||||
extends Socket implements RMIClientSocketFactory, Serializable
|
||||
{
|
||||
ClientSocketAndFactory() {
|
||||
}
|
||||
ClientSocketAndFactory(String host, int port) throws IOException {
|
||||
super(host, port);
|
||||
}
|
||||
|
||||
public Socket createSocket(String host, int port)
|
||||
throws IOException {
|
||||
|
||||
return new ClientSocketAndFactory(host, port);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return getPort();
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
|
||||
if (obj instanceof ClientSocketAndFactory) {
|
||||
ClientSocketAndFactory csf = (ClientSocketAndFactory) obj;
|
||||
if (getPort() == csf.getPort()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
try {
|
||||
System.out.println("\n\nRegression test for, 4251010\n\n");
|
||||
|
||||
Test test = new TestImpl(new ClientSocketAndFactory(),
|
||||
new ServerSocketAndFactory());
|
||||
TestHome home = new TestHomeImpl(test);
|
||||
|
||||
Test test0 = ((Test) RemoteObject.toStub(test));
|
||||
Test test1 = ((TestHome) RemoteObject.toStub(home)).get();
|
||||
Test test2 = ((TestHome) RemoteObject.toStub(home)).get();
|
||||
Test test3 = ((Test) (new MarshalledObject(test)).get());
|
||||
|
||||
if (test0.equals(test1)) {
|
||||
System.out.println("test0, test1, stubs equal");
|
||||
} else {
|
||||
TestLibrary.bomb("test0, test1, stubs not equal");
|
||||
}
|
||||
|
||||
if (test1.equals(test2)) {
|
||||
System.out.println("test1, test2, stubs equal");
|
||||
} else {
|
||||
TestLibrary.bomb("test1, test2, stubs not equal");
|
||||
}
|
||||
|
||||
// explicitly compare an unmarshalled object with toStub
|
||||
// return
|
||||
if (test2.equals(test3)) {
|
||||
System.out.println("test2, test3, stubs equal");
|
||||
} else {
|
||||
TestLibrary.bomb("test2, test3, stubs not equal");
|
||||
}
|
||||
|
||||
test0 = null;
|
||||
test1 = null;
|
||||
test2 = null;
|
||||
test3 = null;
|
||||
|
||||
TestLibrary.unexport(test);
|
||||
TestLibrary.unexport(home);
|
||||
|
||||
System.err.println("test passed: stubs were equal");
|
||||
|
||||
} catch (Exception e) {
|
||||
TestLibrary.bomb("test got unexpected exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
85
test/jdk/java/rmi/server/RemoteServer/AddrInUse.java
Normal file
85
test/jdk/java/rmi/server/RemoteServer/AddrInUse.java
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2025, 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 4111507
|
||||
* @summary retryServerSocket should not retry on BindException
|
||||
*
|
||||
* @run main/othervm AddrInUse
|
||||
*/
|
||||
|
||||
import java.net.ServerSocket;
|
||||
import java.rmi.registry.LocateRegistry;
|
||||
import java.rmi.server.ExportException;
|
||||
|
||||
public class AddrInUse {
|
||||
|
||||
private static volatile Throwable registryExportFailure = null;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
/*
|
||||
* Bind a server socket to a port.
|
||||
*/
|
||||
try (ServerSocket server = new ServerSocket(0)) {
|
||||
int port = server.getLocalPort();
|
||||
System.err.println("Created a ServerSocket on port " + port + "...");
|
||||
|
||||
/*
|
||||
* Start a thread that creates a registry on the same port,
|
||||
* and analyze the result.
|
||||
*/
|
||||
System.err.println("create a registry on the same port...");
|
||||
System.err.println("(should cause an ExportException)");
|
||||
|
||||
Thread exportRegistryThread = new Thread(() -> {
|
||||
/*
|
||||
* Attempt to create (i.e. export) a registry on the port that
|
||||
* has already been bound, and record the result.
|
||||
*/
|
||||
try {
|
||||
LocateRegistry.createRegistry(port);
|
||||
} catch (Throwable t) {
|
||||
registryExportFailure = t;
|
||||
}
|
||||
}, "ExportRegistry-Thread");
|
||||
|
||||
exportRegistryThread.start();
|
||||
|
||||
/*
|
||||
* Wait for the LocateRegistry.createRegistry() call to complete or
|
||||
* if it blocks forever (due to the original bug), then let jtreg fail
|
||||
* the test with a timeout
|
||||
*/
|
||||
exportRegistryThread.join();
|
||||
if (registryExportFailure == null) {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: export on already-bound port succeeded");
|
||||
}
|
||||
if (!(registryExportFailure instanceof ExportException)) {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: unexpected exception occurred", registryExportFailure);
|
||||
}
|
||||
System.err.println("TEST PASSED, received expected exception: " + registryExportFailure);
|
||||
}
|
||||
}
|
||||
}
|
||||
41
test/jdk/java/rmi/server/RemoteServer/SetLogNull.java
Normal file
41
test/jdk/java/rmi/server/RemoteServer/SetLogNull.java
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 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 4639762
|
||||
* @summary The method java.rmi.server.RemoteServer.setLog should never
|
||||
* throw a NullPointerException when its argument is null even if it has
|
||||
* never been invoked before, or even if its last invocation also had an
|
||||
* argument of null.
|
||||
* @author Peter Jones
|
||||
*
|
||||
* @run main/othervm SetLogNull
|
||||
*/
|
||||
|
||||
import java.rmi.server.RemoteServer;
|
||||
|
||||
public class SetLogNull {
|
||||
public static void main(String[] args) {
|
||||
RemoteServer.setLog(null);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2012, 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 4180282
|
||||
* @summary RMI needs a mechanism to dynamically change a VMs RMI
|
||||
* serverHostname. If the java.rmi.server.hostname property is
|
||||
* changed dynamically, newly exported objects should be exported
|
||||
* with the new hostname instead of the value of the
|
||||
* java.rmi.server.hostname property when the first object was exported.
|
||||
*
|
||||
* @author Ann Wollrath
|
||||
*
|
||||
* @build ChangeHostName ChangeHostName_Stub
|
||||
* @run main/othervm ChangeHostName
|
||||
*/
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.server.RemoteObject;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
|
||||
public class ChangeHostName
|
||||
extends UnicastRemoteObject
|
||||
implements Receiver
|
||||
{
|
||||
public ChangeHostName() throws RemoteException {
|
||||
}
|
||||
|
||||
public void receive(Remote obj) {
|
||||
System.err.println("received: " + obj.toString());
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
InetAddress localAddress = InetAddress.getLocalHost();
|
||||
String[] hostlist = new String[] {
|
||||
localAddress.getHostAddress(), localAddress.getHostName() };
|
||||
|
||||
for (int i = 0; i < hostlist.length; i++) {
|
||||
|
||||
System.setProperty("java.rmi.server.hostname", hostlist[i]);
|
||||
Remote impl = new ChangeHostName();
|
||||
System.err.println("\ncreated impl extending URO: " + impl);
|
||||
|
||||
Receiver stub = (Receiver) RemoteObject.toStub(impl);
|
||||
System.err.println("stub for impl: " + stub);
|
||||
|
||||
System.err.println("invoking method on stub");
|
||||
stub.receive(stub);
|
||||
|
||||
UnicastRemoteObject.unexportObject(impl, true);
|
||||
System.err.println("unexported impl");
|
||||
|
||||
if (stub.toString().indexOf(hostlist[i]) >= 0) {
|
||||
System.err.println("stub's ref contains hostname: " +
|
||||
hostlist[i]);
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: stub's ref doesn't contain hostname: " +
|
||||
hostlist[i]);
|
||||
}
|
||||
}
|
||||
System.err.println("TEST PASSED");
|
||||
}
|
||||
}
|
||||
|
||||
interface Receiver extends Remote {
|
||||
void receive(Remote obj) throws RemoteException;
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2008, 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.
|
||||
*/
|
||||
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class ChangeHostName_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements Receiver, java.rmi.Remote
|
||||
{
|
||||
private static final long serialVersionUID = 2;
|
||||
|
||||
private static java.lang.reflect.Method $method_receive_0;
|
||||
|
||||
static {
|
||||
try {
|
||||
$method_receive_0 = Receiver.class.getMethod("receive", new java.lang.Class[] {java.rmi.Remote.class});
|
||||
} catch (java.lang.NoSuchMethodException e) {
|
||||
throw new java.lang.NoSuchMethodError(
|
||||
"stub class initialization failed");
|
||||
}
|
||||
}
|
||||
|
||||
// constructors
|
||||
public ChangeHostName_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
// methods from remote interfaces
|
||||
|
||||
// implementation of receive(Remote)
|
||||
public void receive(java.rmi.Remote $param_Remote_1)
|
||||
throws java.rmi.RemoteException
|
||||
{
|
||||
try {
|
||||
ref.invoke(this, $method_receive_0, new java.lang.Object[] {$param_Remote_1}, 5876293363550629411L);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.rmi.RemoteException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2011, 2012, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 2011 IBM Corporation
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 6597112
|
||||
* @summary GC'ing objects whilst being exported to RMI should not cause exceptions
|
||||
* @author Neil Richards <neil.richards@ngmr.net>, <neil_richards@uk.ibm.com>
|
||||
* @run main/othervm GcDuringExport
|
||||
* @key intermittent
|
||||
*/
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
|
||||
public class GcDuringExport {
|
||||
private static final long MAX_EXPORT_ITERATIONS = 50000;
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Thread gcInducingThread = new Thread() {
|
||||
public void run() {
|
||||
while (true) {
|
||||
System.gc();
|
||||
try { Thread.sleep(1); } catch (InterruptedException e) { }
|
||||
}
|
||||
}
|
||||
};
|
||||
gcInducingThread.setDaemon(true);
|
||||
gcInducingThread.start();
|
||||
|
||||
long i = 0;
|
||||
try {
|
||||
while (i < MAX_EXPORT_ITERATIONS) {
|
||||
i++;
|
||||
UnicastRemoteObject.exportObject(new Remote() { }, 0);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
throw new RuntimeException("Test FAILED on iteration " + i + ".", e);
|
||||
}
|
||||
|
||||
System.out.println("Test successfully exported " + i + " objects.");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,146 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2017, 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 4308492
|
||||
* @summary In addition to keeping the VM alive (with a non-daeman thread)
|
||||
* while there are remote objects exported, the RMI runtime should also
|
||||
* keep it alive while there remain calls in progress (to remote objects
|
||||
* the have presumably been unexported), so that a remote object can more
|
||||
* conveniently implement a graceful remote shutdown method (that unexports
|
||||
* the object).
|
||||
* @author Peter Jones
|
||||
*
|
||||
* @library ../../../testlibrary
|
||||
* @modules java.rmi/sun.rmi.registry
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary JavaVM KeepAliveDuringCall_Stub
|
||||
* ShutdownMonitor Shutdown ShutdownImpl ShutdownImpl_Stub
|
||||
* @run main/othervm KeepAliveDuringCall
|
||||
*/
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.registry.LocateRegistry;
|
||||
import java.rmi.registry.Registry;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
|
||||
public class KeepAliveDuringCall implements ShutdownMonitor {
|
||||
|
||||
public static final String BINDING = "KeepAliveDuringCall";
|
||||
private static final int TIMEOUT = 20000;
|
||||
|
||||
private Object lock = new Object();
|
||||
private Shutdown shutdown = null;
|
||||
private boolean stillAlive = false;
|
||||
|
||||
public void submitShutdown(Shutdown shutdown) {
|
||||
synchronized (lock) {
|
||||
this.shutdown = shutdown;
|
||||
lock.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
public void declareStillAlive() {
|
||||
synchronized (lock) {
|
||||
stillAlive = true;
|
||||
lock.notifyAll();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
System.err.println("\nRegression test for bug 4308492\n");
|
||||
|
||||
KeepAliveDuringCall obj = new KeepAliveDuringCall();
|
||||
JavaVM jvm = null;
|
||||
|
||||
try {
|
||||
UnicastRemoteObject.exportObject(obj);
|
||||
System.err.println("exported shutdown monitor");
|
||||
|
||||
Registry localRegistry = TestLibrary.createRegistryOnEphemeralPort();
|
||||
int registryPort = TestLibrary.getRegistryPort(localRegistry);
|
||||
System.err.println("created local registry");
|
||||
|
||||
localRegistry.bind(BINDING, obj);
|
||||
System.err.println("bound shutdown monitor in local registry");
|
||||
|
||||
System.err.println("starting remote ShutdownImpl VM...");
|
||||
jvm = new JavaVM("ShutdownImpl",
|
||||
"-Drmi.registry.port=" +
|
||||
registryPort, "");
|
||||
jvm.start();
|
||||
|
||||
Shutdown s;
|
||||
synchronized (obj.lock) {
|
||||
System.err.println(
|
||||
"waiting for submission of object to shutdown...");
|
||||
while ((s = obj.shutdown) == null) {
|
||||
obj.lock.wait(TIMEOUT);
|
||||
}
|
||||
if (s == null) {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: timeout waiting for shutdown object " +
|
||||
"to make initial contact");
|
||||
}
|
||||
System.err.println("shutdown object submitted: " + s);
|
||||
}
|
||||
|
||||
try {
|
||||
s.shutdown();
|
||||
} catch (RemoteException e) {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: shutdown method threw remote exception", e);
|
||||
}
|
||||
|
||||
synchronized (obj.lock) {
|
||||
if (!obj.stillAlive) {
|
||||
throw new RuntimeException("TEST FAILED: " +
|
||||
"shutdown object not detected alive after unexport");
|
||||
}
|
||||
}
|
||||
|
||||
System.err.println("TEST PASSED: " +
|
||||
"shutdown object detected still alive after unexport");
|
||||
|
||||
} catch (Exception e) {
|
||||
if (e instanceof RuntimeException) {
|
||||
throw (RuntimeException) e;
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: unexpected exception", e);
|
||||
}
|
||||
} finally {
|
||||
if (jvm != null) {
|
||||
jvm.destroy();
|
||||
}
|
||||
try {
|
||||
UnicastRemoteObject.unexportObject(obj, true);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2008, 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.
|
||||
*/
|
||||
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class KeepAliveDuringCall_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements ShutdownMonitor
|
||||
{
|
||||
private static final long serialVersionUID = 2;
|
||||
|
||||
private static java.lang.reflect.Method $method_declareStillAlive_0;
|
||||
private static java.lang.reflect.Method $method_submitShutdown_1;
|
||||
|
||||
static {
|
||||
try {
|
||||
$method_declareStillAlive_0 = ShutdownMonitor.class.getMethod("declareStillAlive", new java.lang.Class[] {});
|
||||
$method_submitShutdown_1 = ShutdownMonitor.class.getMethod("submitShutdown", new java.lang.Class[] {Shutdown.class});
|
||||
} catch (java.lang.NoSuchMethodException e) {
|
||||
throw new java.lang.NoSuchMethodError(
|
||||
"stub class initialization failed");
|
||||
}
|
||||
}
|
||||
|
||||
// constructors
|
||||
public KeepAliveDuringCall_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
// methods from remote interfaces
|
||||
|
||||
// implementation of declareStillAlive()
|
||||
public void declareStillAlive()
|
||||
throws java.rmi.RemoteException
|
||||
{
|
||||
try {
|
||||
ref.invoke(this, $method_declareStillAlive_0, null, -1562228924246272634L);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.rmi.RemoteException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of submitShutdown(Shutdown)
|
||||
public void submitShutdown(Shutdown $param_Shutdown_1)
|
||||
throws java.rmi.RemoteException
|
||||
{
|
||||
try {
|
||||
ref.invoke(this, $method_submitShutdown_1, new java.lang.Object[] {$param_Shutdown_1}, 7574258166120515108L);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.rmi.RemoteException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2008, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
|
||||
public interface Shutdown extends Remote {
|
||||
void shutdown() throws RemoteException;
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2012, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.registry.LocateRegistry;
|
||||
import java.rmi.registry.Registry;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
|
||||
public class ShutdownImpl implements Shutdown {
|
||||
|
||||
private static Remote impl; // rooted here to prevent GC
|
||||
|
||||
private final ShutdownMonitor monitor;
|
||||
|
||||
private ShutdownImpl(ShutdownMonitor monitor) {
|
||||
this.monitor = monitor;
|
||||
}
|
||||
|
||||
public void shutdown() {
|
||||
try {
|
||||
System.err.println(
|
||||
"(ShutdownImpl.shutdown) shutdown method invoked:");
|
||||
|
||||
UnicastRemoteObject.unexportObject(this, true);
|
||||
System.err.println(
|
||||
"(ShutdownImpl.shutdown) shutdown object unexported");
|
||||
|
||||
Thread.sleep(500);
|
||||
System.err.println("(ShutDownImpl.shutdown) FEE");
|
||||
Thread.sleep(500);
|
||||
System.err.println("(ShutDownImpl.shutdown) FIE");
|
||||
Thread.sleep(500);
|
||||
System.err.println("(ShutDownImpl.shutdown) FOE");
|
||||
Thread.sleep(500);
|
||||
System.err.println("(ShutDownImpl.shutdown) FOO");
|
||||
|
||||
monitor.declareStillAlive();
|
||||
System.err.println("(ShutDownImpl.shutdown) still alive!");
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(
|
||||
"unexpected exception occurred in shutdown method", e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
int registryPort = Integer.parseInt(System.getProperty("rmi.registry.port"));
|
||||
Registry registry =
|
||||
LocateRegistry.getRegistry("", registryPort);
|
||||
ShutdownMonitor monitor = (ShutdownMonitor)
|
||||
registry.lookup(KeepAliveDuringCall.BINDING);
|
||||
System.err.println("(ShutdownImpl) retrieved shutdown monitor");
|
||||
|
||||
impl = new ShutdownImpl(monitor);
|
||||
Shutdown stub = (Shutdown) UnicastRemoteObject.exportObject(impl);
|
||||
System.err.println("(ShutdownImpl) exported shutdown object");
|
||||
|
||||
monitor.submitShutdown(stub);
|
||||
System.err.println("(ShutdownImpl) submitted shutdown object");
|
||||
|
||||
} catch (Exception e) {
|
||||
System.err.println("(ShutdownImpl) TEST SUBPROCESS FAILURE:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2008, 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.
|
||||
*/
|
||||
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class ShutdownImpl_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements Shutdown
|
||||
{
|
||||
private static final long serialVersionUID = 2;
|
||||
|
||||
private static java.lang.reflect.Method $method_shutdown_0;
|
||||
|
||||
static {
|
||||
try {
|
||||
$method_shutdown_0 = Shutdown.class.getMethod("shutdown", new java.lang.Class[] {});
|
||||
} catch (java.lang.NoSuchMethodException e) {
|
||||
throw new java.lang.NoSuchMethodError(
|
||||
"stub class initialization failed");
|
||||
}
|
||||
}
|
||||
|
||||
// constructors
|
||||
public ShutdownImpl_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
// methods from remote interfaces
|
||||
|
||||
// implementation of shutdown()
|
||||
public void shutdown()
|
||||
throws java.rmi.RemoteException
|
||||
{
|
||||
try {
|
||||
ref.invoke(this, $method_shutdown_0, null, -7207851917985848402L);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.rmi.RemoteException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2008, 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
|
||||
public interface ShutdownMonitor extends Remote {
|
||||
void submitShutdown(Shutdown shutdown) throws RemoteException;
|
||||
void declareStillAlive() throws RemoteException;
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2012, 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 4353388
|
||||
* @summary After an instance of UnicastRemoteObject has been unexported,
|
||||
* if it gets marshalled, an InternalError should not be thrown; instead,
|
||||
* the marshalling should succeed. Also, if its "local" LiveRef gets
|
||||
* marshalled, by way of the stub returned by RemoteObject.toStub, for
|
||||
* example, then that should also succeed, instead of throwing an
|
||||
* IOException (see fix for bugid 4017232).
|
||||
* @author Peter Jones
|
||||
*
|
||||
* @build MarshalAfterUnexport MarshalAfterUnexport_Stub
|
||||
* @run main/othervm MarshalAfterUnexport
|
||||
*/
|
||||
|
||||
import java.rmi.MarshalledObject;
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.server.RemoteObject;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
|
||||
public class MarshalAfterUnexport
|
||||
extends UnicastRemoteObject
|
||||
implements Receiver
|
||||
{
|
||||
public MarshalAfterUnexport() throws RemoteException {
|
||||
}
|
||||
|
||||
public void receive(Remote obj) {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Remote impl2 = null;
|
||||
try {
|
||||
Remote impl = new MarshalAfterUnexport();
|
||||
System.err.println("created impl extending URO: " + impl);
|
||||
|
||||
Receiver stub = (Receiver) RemoteObject.toStub(impl);
|
||||
System.err.println("stub for impl: " + stub);
|
||||
|
||||
UnicastRemoteObject.unexportObject(impl, true);
|
||||
System.err.println("unexported impl");
|
||||
|
||||
impl2 = new MarshalAfterUnexport();
|
||||
Receiver stub2 = (Receiver) RemoteObject.toStub(impl2);
|
||||
|
||||
System.err.println("marshalling unexported object:");
|
||||
MarshalledObject mobj = new MarshalledObject(impl);
|
||||
|
||||
System.err.println("passing unexported object via RMI-JRMP:");
|
||||
stub2.receive(stub);
|
||||
|
||||
System.err.println("TEST PASSED");
|
||||
} finally {
|
||||
if (impl2 != null) {
|
||||
try {
|
||||
UnicastRemoteObject.unexportObject(impl2, true);
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface Receiver extends Remote {
|
||||
void receive(Remote obj) throws RemoteException;
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2012, 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 4513223
|
||||
* @summary After an instance of UnicastRemoteObject has been unexported,
|
||||
* if it gets marshalled, an InternalError should not be thrown; instead,
|
||||
* the marshalling should succeed. Also, if its "local" LiveRef gets
|
||||
* marshalled, by way of the stub returned by RemoteObject.toStub, for
|
||||
* example, then that should also succeed, instead of throwing an
|
||||
* IOException (see fixes for bugids 4353388, 4017232). This test
|
||||
* handles the case where the impl's RemoteRef is a UnicastServerRef2.
|
||||
* @author Peter Jones
|
||||
* @author Ann Wollrath
|
||||
*
|
||||
* @build MarshalAfterUnexport2 MarshalAfterUnexport2_Stub
|
||||
* @run main/othervm MarshalAfterUnexport2
|
||||
*/
|
||||
|
||||
import java.rmi.MarshalledObject;
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.server.RemoteObject;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
|
||||
public class MarshalAfterUnexport2
|
||||
extends UnicastRemoteObject
|
||||
implements Receiver
|
||||
{
|
||||
public MarshalAfterUnexport2() throws RemoteException {
|
||||
super(0, null, null);
|
||||
}
|
||||
|
||||
public void receive(Remote obj) {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
System.err.println("\nRegression test for bug 4513223\n");
|
||||
|
||||
Remote impl2 = null;
|
||||
try {
|
||||
Remote impl = new MarshalAfterUnexport2();
|
||||
System.err.println(
|
||||
"created impl extending URO (with a UnicastServerRef2): " +
|
||||
impl);
|
||||
|
||||
Receiver stub = (Receiver) RemoteObject.toStub(impl);
|
||||
System.err.println("stub for impl: " + stub);
|
||||
|
||||
UnicastRemoteObject.unexportObject(impl, true);
|
||||
System.err.println("unexported impl");
|
||||
|
||||
impl2 = new MarshalAfterUnexport2();
|
||||
Receiver stub2 = (Receiver) RemoteObject.toStub(impl2);
|
||||
|
||||
System.err.println("marshalling unexported object:");
|
||||
MarshalledObject mobj = new MarshalledObject(impl);
|
||||
|
||||
System.err.println("passing unexported object via RMI-JRMP:");
|
||||
stub2.receive(stub);
|
||||
|
||||
System.err.println("TEST PASSED");
|
||||
} finally {
|
||||
if (impl2 != null) {
|
||||
try {
|
||||
UnicastRemoteObject.unexportObject(impl2, true);
|
||||
} catch (Throwable t) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface Receiver extends Remote {
|
||||
void receive(Remote obj) throws RemoteException;
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2002, 2008, 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.
|
||||
*/
|
||||
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class MarshalAfterUnexport2_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements Receiver, java.rmi.Remote
|
||||
{
|
||||
private static final long serialVersionUID = 2;
|
||||
|
||||
private static java.lang.reflect.Method $method_receive_0;
|
||||
|
||||
static {
|
||||
try {
|
||||
$method_receive_0 = Receiver.class.getMethod("receive", new java.lang.Class[] {java.rmi.Remote.class});
|
||||
} catch (java.lang.NoSuchMethodException e) {
|
||||
throw new java.lang.NoSuchMethodError(
|
||||
"stub class initialization failed");
|
||||
}
|
||||
}
|
||||
|
||||
// constructors
|
||||
public MarshalAfterUnexport2_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
// methods from remote interfaces
|
||||
|
||||
// implementation of receive(Remote)
|
||||
public void receive(java.rmi.Remote $param_Remote_1)
|
||||
throws java.rmi.RemoteException
|
||||
{
|
||||
try {
|
||||
ref.invoke(this, $method_receive_0, new java.lang.Object[] {$param_Remote_1}, 5876293363550629411L);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.rmi.RemoteException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2008, 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.
|
||||
*/
|
||||
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class MarshalAfterUnexport_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements Receiver, java.rmi.Remote
|
||||
{
|
||||
private static final long serialVersionUID = 2;
|
||||
|
||||
private static java.lang.reflect.Method $method_receive_0;
|
||||
|
||||
static {
|
||||
try {
|
||||
$method_receive_0 = Receiver.class.getMethod("receive", new java.lang.Class[] {java.rmi.Remote.class});
|
||||
} catch (java.lang.NoSuchMethodException e) {
|
||||
throw new java.lang.NoSuchMethodError(
|
||||
"stub class initialization failed");
|
||||
}
|
||||
}
|
||||
|
||||
// constructors
|
||||
public MarshalAfterUnexport_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
// methods from remote interfaces
|
||||
|
||||
// implementation of receive(Remote)
|
||||
public void receive(java.rmi.Remote $param_Remote_1)
|
||||
throws java.rmi.RemoteException
|
||||
{
|
||||
try {
|
||||
ref.invoke(this, $method_receive_0, new java.lang.Object[] {$param_Remote_1}, 5876293363550629411L);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.rmi.RemoteException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
import java.io.InvalidClassException;
|
||||
import java.io.ObjectInputFilter;
|
||||
import java.io.Serializable;
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.UnmarshalException;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.lang.ref.Reference;
|
||||
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @run testng/othervm FilterUROTest
|
||||
* @summary Check that objects are exported with ObjectInputFilters via UnicastRemoteObject
|
||||
*/
|
||||
public class FilterUROTest {
|
||||
|
||||
/**
|
||||
* Data to test serialFilter call counts.
|
||||
* - name
|
||||
* - Object
|
||||
* - expected count of calls to checkInput.
|
||||
*
|
||||
* @return array of test data
|
||||
*/
|
||||
@DataProvider(name = "bindData")
|
||||
static Object[][] bindObjects() {
|
||||
Object[][] data = {
|
||||
{"SimpleString", "SimpleString", 0},
|
||||
{"String", new XX("now is the time"), 1},
|
||||
{"String[]", new XX(new String[3]), 3},
|
||||
{"Long[4]", new XX(new Long[4]), 3},
|
||||
{"RejectME", new XX(new RejectME()), -1},
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test exporting an object with a serialFilter using exportObject().
|
||||
* Send some objects and check the number of calls to the serialFilter.
|
||||
*/
|
||||
@Test(dataProvider = "bindData")
|
||||
public void useExportObject(String name, Object obj, int expectedFilterCount) throws RemoteException {
|
||||
try {
|
||||
RemoteImpl impl = RemoteImpl.create();
|
||||
Echo client = (Echo) UnicastRemoteObject
|
||||
.exportObject(impl, 0, impl.checker);
|
||||
int count = client.filterCount(obj);
|
||||
System.out.printf("count: %d, obj: %s%n", count, obj);
|
||||
Assert.assertEquals(count, expectedFilterCount, "wrong number of filter calls");
|
||||
Reference.reachabilityFence(impl);
|
||||
} catch (RemoteException rex) {
|
||||
if (expectedFilterCount == -1 &&
|
||||
UnmarshalException.class.equals(rex.getCause().getClass()) &&
|
||||
InvalidClassException.class.equals(rex.getCause().getCause().getClass())) {
|
||||
return; // normal expected exception
|
||||
}
|
||||
rex.printStackTrace();
|
||||
Assert.fail("unexpected remote exception", rex);
|
||||
} catch (Exception rex) {
|
||||
Assert.fail("unexpected exception", rex);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Test exporting an object with a serialFilter using exportObject()
|
||||
* with explicit (but null) SocketFactories.
|
||||
* Send some objects and check the number of calls to the serialFilter.
|
||||
*/
|
||||
@Test(dataProvider = "bindData")
|
||||
public void useExportObject2(String name, Object obj, int expectedFilterCount) throws RemoteException {
|
||||
try {
|
||||
RemoteImpl impl = RemoteImpl.create();
|
||||
Echo client = (Echo) UnicastRemoteObject
|
||||
.exportObject(impl, 0, null, null, impl.checker);
|
||||
int count = client.filterCount(obj);
|
||||
System.out.printf("count: %d, obj: %s%n", count, obj);
|
||||
Assert.assertEquals(count, expectedFilterCount, "wrong number of filter calls");
|
||||
Reference.reachabilityFence(impl);
|
||||
} catch (RemoteException rex) {
|
||||
if (expectedFilterCount == -1 &&
|
||||
UnmarshalException.class.equals(rex.getCause().getClass()) &&
|
||||
InvalidClassException.class.equals(rex.getCause().getCause().getClass())) {
|
||||
return; // normal expected exception
|
||||
}
|
||||
rex.printStackTrace();
|
||||
Assert.fail("unexpected remote exception", rex);
|
||||
} catch (Exception rex) {
|
||||
Assert.fail("unexpected exception", rex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple Serializable holding an object that is passed by value.
|
||||
* It and its contents are checked by the filter.
|
||||
*/
|
||||
static class XX implements Serializable {
|
||||
private static final long serialVersionUID = 362498820763181265L;
|
||||
|
||||
final Object obj;
|
||||
|
||||
XX(Object obj) {
|
||||
this.obj = obj;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return super.toString() + "//" + Objects.toString(obj);
|
||||
}
|
||||
}
|
||||
|
||||
interface Echo extends Remote {
|
||||
int filterCount(Object obj) throws RemoteException;
|
||||
}
|
||||
|
||||
/**
|
||||
* This remote object just counts the calls to the serialFilter
|
||||
* and returns it. The caller can check the number against
|
||||
* what was expected for the object passed as an argument.
|
||||
* A new RemoteImpl is used for each test so the count starts at zero again.
|
||||
*/
|
||||
static class RemoteImpl implements Echo {
|
||||
|
||||
private static final long serialVersionUID = -6999613679881262446L;
|
||||
|
||||
transient Checker checker;
|
||||
|
||||
static RemoteImpl create() throws RemoteException {
|
||||
RemoteImpl impl = new RemoteImpl(new Checker());
|
||||
return impl;
|
||||
}
|
||||
|
||||
private RemoteImpl(Checker checker) throws RemoteException {
|
||||
this.checker = checker;
|
||||
}
|
||||
|
||||
public int filterCount(Object obj) throws RemoteException {
|
||||
return checker.count();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A ObjectInputFilter that just counts when it is called.
|
||||
*/
|
||||
static class Checker implements ObjectInputFilter {
|
||||
int count;
|
||||
|
||||
@Override
|
||||
public Status checkInput(FilterInfo filterInfo) {
|
||||
if (filterInfo.serialClass() == RejectME.class) {
|
||||
return Status.REJECTED;
|
||||
}
|
||||
count++;
|
||||
return Status.UNDECIDED;
|
||||
}
|
||||
|
||||
public int count() {
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A class to be rejected by the filter.
|
||||
*/
|
||||
static class RejectME implements Serializable {
|
||||
private static final long serialVersionUID = 2L;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2008, 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.
|
||||
*/
|
||||
|
||||
import java.rmi.*;
|
||||
|
||||
public interface Ping extends Remote {
|
||||
public void ping() throws RemoteException;
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 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 4331349
|
||||
* @summary synopsis: unexporting doesn't guarantee that DGC will
|
||||
* let go of remote object
|
||||
*
|
||||
* @author Ann Wollrath
|
||||
*
|
||||
* @library ../../../testlibrary
|
||||
* @modules java.rmi/sun.rmi.registry
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary UnexportLeak_Stub Ping
|
||||
* @run main/othervm UnexportLeak
|
||||
*/
|
||||
|
||||
import java.lang.ref.*;
|
||||
import java.rmi.*;
|
||||
import java.rmi.server.*;
|
||||
import java.rmi.registry.*;
|
||||
|
||||
public class UnexportLeak implements Ping {
|
||||
public void ping() {
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
System.err.println("\nRegression test for bug 4331349\n");
|
||||
Registry registry = TestLibrary.createRegistryOnEphemeralPort();
|
||||
int registryPort = TestLibrary.getRegistryPort(registry);
|
||||
Remote obj = new UnexportLeak();
|
||||
WeakReference wr = new WeakReference(obj);
|
||||
UnicastRemoteObject.exportObject(obj);
|
||||
LocateRegistry.getRegistry(registryPort).rebind("UnexportLeak", obj);
|
||||
UnicastRemoteObject.unexportObject(obj, true);
|
||||
obj = null;
|
||||
flushRefs();
|
||||
if (wr.get() != null) {
|
||||
System.err.println("FAILED: unexported object not collected");
|
||||
throw new RuntimeException(
|
||||
"FAILED: unexported object not collected");
|
||||
} else {
|
||||
System.err.println("PASSED: unexported object collected");
|
||||
}
|
||||
} catch (RemoteException e) {
|
||||
System.err.println(
|
||||
"FAILED: RemoteException encountered: " + e.getMessage());
|
||||
e.printStackTrace();
|
||||
throw new RuntimeException("FAILED: RemoteException encountered");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Force desparate garbage collection so that all WeakReference instances
|
||||
* will be cleared.
|
||||
*/
|
||||
private static void flushRefs() {
|
||||
java.util.Vector chain = new java.util.Vector();
|
||||
try {
|
||||
while (true) {
|
||||
int[] hungry = new int[65536];
|
||||
chain.addElement(hungry);
|
||||
}
|
||||
} catch (OutOfMemoryError e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2008, 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.
|
||||
*/
|
||||
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class UnexportLeak_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements Ping
|
||||
{
|
||||
private static final long serialVersionUID = 2;
|
||||
|
||||
private static java.lang.reflect.Method $method_ping_0;
|
||||
|
||||
static {
|
||||
try {
|
||||
$method_ping_0 = Ping.class.getMethod("ping", new java.lang.Class[] {});
|
||||
} catch (java.lang.NoSuchMethodException e) {
|
||||
throw new java.lang.NoSuchMethodError(
|
||||
"stub class initialization failed");
|
||||
}
|
||||
}
|
||||
|
||||
// constructors
|
||||
public UnexportLeak_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
// methods from remote interfaces
|
||||
|
||||
// implementation of ping()
|
||||
public void ping()
|
||||
throws java.rmi.RemoteException
|
||||
{
|
||||
try {
|
||||
ref.invoke(this, $method_ping_0, null, 5866401369815527589L);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.rmi.RemoteException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2024, 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 4507539
|
||||
* @summary support using dynamic proxies as RMI stubs
|
||||
* @author Ann Wollrath
|
||||
*
|
||||
* @build UseDynamicProxies UseDynamicProxies_Stub
|
||||
* @run main/othervm/timeout=240 UseDynamicProxies true
|
||||
* @run main/othervm/timeout=240 UseDynamicProxies
|
||||
* false
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Proxy;
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.server.RemoteObjectInvocationHandler;
|
||||
import java.rmi.server.RemoteStub;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
|
||||
public class UseDynamicProxies implements RemoteInterface {
|
||||
|
||||
|
||||
public Object passObject(Object obj) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
public int passInt(int x) {
|
||||
return x;
|
||||
}
|
||||
|
||||
public String passString(String string) {
|
||||
return string;
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
RemoteInterface server = null;
|
||||
RemoteInterface proxy = null;
|
||||
|
||||
try {
|
||||
System.setProperty("java.rmi.server.ignoreStubClasses", args[0]);
|
||||
boolean ignoreStubClasses = Boolean.parseBoolean(args[0]);
|
||||
|
||||
System.err.println("export object");
|
||||
server = new UseDynamicProxies();
|
||||
proxy =
|
||||
(RemoteInterface) UnicastRemoteObject.exportObject(server, 0);
|
||||
|
||||
System.err.println("proxy = " + proxy);
|
||||
if (ignoreStubClasses) {
|
||||
if (!Proxy.isProxyClass(proxy.getClass())) {
|
||||
throw new RuntimeException(
|
||||
"server proxy is not a dynamic proxy");
|
||||
}
|
||||
if (!(Proxy.getInvocationHandler(proxy) instanceof
|
||||
RemoteObjectInvocationHandler))
|
||||
{
|
||||
throw new RuntimeException("invalid invocation handler");
|
||||
}
|
||||
|
||||
} else if (!(proxy instanceof RemoteStub)) {
|
||||
throw new RuntimeException(
|
||||
"server proxy is not a RemoteStub");
|
||||
}
|
||||
|
||||
System.err.println("invoke methods");
|
||||
Object obj = proxy.passObject(proxy);
|
||||
if (!proxy.equals(obj)) {
|
||||
throw new RuntimeException("returned proxy not equal");
|
||||
}
|
||||
|
||||
int x = proxy.passInt(53);
|
||||
if (x != 53) {
|
||||
throw new RuntimeException("returned int not equal");
|
||||
}
|
||||
|
||||
String string = proxy.passString("test");
|
||||
if (!string.equals("test")) {
|
||||
throw new RuntimeException("returned string not equal");
|
||||
}
|
||||
|
||||
System.err.println("TEST PASSED");
|
||||
|
||||
} finally {
|
||||
if (proxy != null) {
|
||||
UnicastRemoteObject.unexportObject(server, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface RemoteInterface extends Remote {
|
||||
Object passObject(Object obj) throws IOException;
|
||||
int passInt(int x) throws IOException;
|
||||
String passString(String string) throws IOException;
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (c) 2003, 2008, 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.
|
||||
*/
|
||||
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class UseDynamicProxies_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements RemoteInterface
|
||||
{
|
||||
private static final long serialVersionUID = 2;
|
||||
|
||||
private static java.lang.reflect.Method $method_passInt_0;
|
||||
private static java.lang.reflect.Method $method_passObject_1;
|
||||
private static java.lang.reflect.Method $method_passString_2;
|
||||
|
||||
static {
|
||||
try {
|
||||
$method_passInt_0 = RemoteInterface.class.getMethod("passInt", new java.lang.Class[] {int.class});
|
||||
$method_passObject_1 = RemoteInterface.class.getMethod("passObject", new java.lang.Class[] {java.lang.Object.class});
|
||||
$method_passString_2 = RemoteInterface.class.getMethod("passString", new java.lang.Class[] {java.lang.String.class});
|
||||
} catch (java.lang.NoSuchMethodException e) {
|
||||
throw new java.lang.NoSuchMethodError(
|
||||
"stub class initialization failed");
|
||||
}
|
||||
}
|
||||
|
||||
// constructors
|
||||
public UseDynamicProxies_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
// methods from remote interfaces
|
||||
|
||||
// implementation of passInt(int)
|
||||
public int passInt(int $param_int_1)
|
||||
throws java.io.IOException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_passInt_0, new java.lang.Object[] {new java.lang.Integer($param_int_1)}, 8655249712495061761L);
|
||||
return ((java.lang.Integer) $result).intValue();
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of passObject(Object)
|
||||
public java.lang.Object passObject(java.lang.Object $param_Object_1)
|
||||
throws java.io.IOException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_passObject_1, new java.lang.Object[] {$param_Object_1}, 3074202549763602823L);
|
||||
return ((java.lang.Object) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of passString(String)
|
||||
public java.lang.String passString(java.lang.String $param_String_1)
|
||||
throws java.io.IOException
|
||||
{
|
||||
try {
|
||||
Object $result = ref.invoke(this, $method_passString_2, new java.lang.Object[] {$param_String_1}, 6627880292288702000L);
|
||||
return ((java.lang.String) $result);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.io.IOException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2018, 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.
|
||||
*/
|
||||
|
||||
import java.io.InvalidClassException;
|
||||
import java.io.ObjectInputFilter;
|
||||
import java.io.Serializable;
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.UnmarshalException;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import sun.rmi.server.UnicastServerRef;
|
||||
import sun.rmi.server.UnicastServerRef2;
|
||||
import sun.rmi.transport.LiveRef;
|
||||
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @modules java.rmi/sun.rmi.registry
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @run testng/othervm FilterUSRTest
|
||||
* @summary Check objects exported with ObjectInputFilters via internal UnicastServerRef(2)
|
||||
*/
|
||||
public class FilterUSRTest {
|
||||
|
||||
/**
|
||||
* Data to test serialFilter call counts.
|
||||
* - name
|
||||
* - Object
|
||||
* - expected count of calls to checkInput.
|
||||
*
|
||||
* @return array of test data
|
||||
*/
|
||||
@DataProvider(name = "bindData")
|
||||
static Object[][] bindObjects() {
|
||||
Object[][] data = {
|
||||
{"SimpleString", "SimpleString", 0},
|
||||
{"String", new XX("now is the time"), 1},
|
||||
{"String[]", new XX(new String[3]), 3},
|
||||
{"Long[4]", new XX(new Long[4]), 3},
|
||||
{"RejectME", new XX(new RejectME()), -1},
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
/*
|
||||
* Test exporting an object with a serialFilter using UnicastServerRef.exportObject().
|
||||
* Send some objects and check the number of calls to the serialFilter.
|
||||
*/
|
||||
@Test(dataProvider = "bindData")
|
||||
public void UnicastServerRef(String name, Object obj, int expectedFilterCount) throws RemoteException {
|
||||
try {
|
||||
RemoteImpl impl = RemoteImpl.create();
|
||||
UnicastServerRef ref = new UnicastServerRef(new LiveRef(0), impl.checker);
|
||||
|
||||
Echo client = (Echo) ref.exportObject(impl, null, false);
|
||||
|
||||
int count = client.filterCount(obj);
|
||||
System.out.printf("count: %d, obj: %s%n", count, obj);
|
||||
Assert.assertEquals(count, expectedFilterCount, "wrong number of filter calls");
|
||||
} catch (RemoteException rex) {
|
||||
if (expectedFilterCount == -1 &&
|
||||
UnmarshalException.class.equals(rex.getCause().getClass()) &&
|
||||
InvalidClassException.class.equals(rex.getCause().getCause().getClass())) {
|
||||
return; // normal expected exception
|
||||
}
|
||||
rex.printStackTrace();
|
||||
Assert.fail("unexpected remote exception", rex);
|
||||
} catch (Exception ex) {
|
||||
Assert.fail("unexpected exception", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Test exporting an object with a serialFilter using UnicastServerRef2.exportObject()
|
||||
* with explicit (but null) SocketFactories.
|
||||
* Send some objects and check the number of calls to the serialFilter.
|
||||
*/
|
||||
@Test(dataProvider = "bindData")
|
||||
public void UnicastServerRef2(String name, Object obj, int expectedFilterCount) throws RemoteException {
|
||||
try {
|
||||
RemoteImpl impl = RemoteImpl.create();
|
||||
UnicastServerRef2 ref = new UnicastServerRef2(0, null, null, impl.checker);
|
||||
|
||||
Echo client = (Echo) ref.exportObject(impl, null, false);
|
||||
|
||||
int count = client.filterCount(obj);
|
||||
System.out.printf("count: %d, obj: %s%n", count, obj);
|
||||
Assert.assertEquals(count, expectedFilterCount, "wrong number of filter calls");
|
||||
} catch (RemoteException rex) {
|
||||
if (expectedFilterCount == -1 &&
|
||||
UnmarshalException.class.equals(rex.getCause().getClass()) &&
|
||||
InvalidClassException.class.equals(rex.getCause().getCause().getClass())) {
|
||||
return; // normal expected exception
|
||||
}
|
||||
rex.printStackTrace();
|
||||
Assert.fail("unexpected remote exception", rex);
|
||||
} catch (Exception rex) {
|
||||
Assert.fail("unexpected exception", rex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple Serializable holding an object that is passed by value.
|
||||
* It and its contents are checked by the filter.
|
||||
*/
|
||||
static class XX implements Serializable {
|
||||
private static final long serialVersionUID = 362498820763181265L;
|
||||
|
||||
final Object obj;
|
||||
|
||||
XX(Object obj) {
|
||||
this.obj = obj;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return super.toString() + "//" + Objects.toString(obj);
|
||||
}
|
||||
}
|
||||
|
||||
interface Echo extends Remote {
|
||||
int filterCount(Object obj) throws RemoteException;
|
||||
}
|
||||
|
||||
/**
|
||||
* This remote object just counts the calls to the serialFilter
|
||||
* and returns it. The caller can check the number against
|
||||
* what was expected for the object passed as an argument.
|
||||
* A new RemoteImpl is used for each test so the count starts at zero again.
|
||||
*/
|
||||
static class RemoteImpl implements Echo {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
transient Checker checker;
|
||||
|
||||
static RemoteImpl create() throws RemoteException {
|
||||
RemoteImpl impl = new RemoteImpl(new Checker());
|
||||
return impl;
|
||||
}
|
||||
|
||||
private RemoteImpl(Checker checker) throws RemoteException {
|
||||
this.checker = checker;
|
||||
}
|
||||
|
||||
public int filterCount(Object obj) throws RemoteException {
|
||||
return checker.count();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A ObjectInputFilter that just counts when it is called.
|
||||
*/
|
||||
static class Checker implements ObjectInputFilter {
|
||||
int count;
|
||||
|
||||
@Override
|
||||
public Status checkInput(ObjectInputFilter.FilterInfo info) {
|
||||
if (info.serialClass() == RejectME.class) {
|
||||
return Status.REJECTED;
|
||||
}
|
||||
count++;
|
||||
return Status.UNDECIDED;
|
||||
}
|
||||
|
||||
public int count() {
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A class to be rejected by the filter.
|
||||
*/
|
||||
static class RejectME implements Serializable {
|
||||
private static final long serialVersionUID = 2L;
|
||||
}
|
||||
|
||||
}
|
||||
47
test/jdk/java/rmi/server/Unmarshal/PrimitiveClasses.java
Normal file
47
test/jdk/java/rmi/server/Unmarshal/PrimitiveClasses.java
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2012, 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 4442373
|
||||
* @summary Verify that RMI can successfully unmarshal Class objects for
|
||||
* primitive types. This test does not affect VM global state,
|
||||
* so othervm is not required.
|
||||
* @run main PrimitiveClasses
|
||||
*/
|
||||
|
||||
import java.rmi.MarshalledObject;
|
||||
|
||||
public class PrimitiveClasses {
|
||||
public static void main(String[] args) throws Exception {
|
||||
Class[] primClasses = {
|
||||
boolean.class, byte.class, char.class, short.class,
|
||||
int.class, long.class, float.class, double.class
|
||||
};
|
||||
for (int i = 0; i < primClasses.length; i++) {
|
||||
Class pc = primClasses[i];
|
||||
if (new MarshalledObject(pc).get() != pc) {
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2012, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
/*
|
||||
* Interface with methods to exercise RMI parameter marshalling
|
||||
* and unmarshalling.
|
||||
*/
|
||||
interface CheckUnmarshal extends java.rmi.Remote {
|
||||
public PoisonPill getPoisonPill() throws RemoteException;
|
||||
public Object ping() throws RemoteException;
|
||||
public void passRuntimeExceptionParameter(
|
||||
RuntimeExceptionParameter rep)
|
||||
throws RemoteException;
|
||||
}
|
||||
|
|
@ -0,0 +1,199 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2012, 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 4118600
|
||||
* @summary RMI UnmarshallException, interaction on stopping a thread.
|
||||
*
|
||||
* @bug 4177704
|
||||
* @summary RuntimeExceptions can corrupt call connections that may be reused.
|
||||
*
|
||||
* @author Laird Dornin
|
||||
*
|
||||
* @library ../../../testlibrary
|
||||
* @modules java.rmi/sun.rmi.registry
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary CheckUnmarshal CheckUnmarshalOnStopThread_Stub
|
||||
* PoisonPill RuntimeExceptionParameter
|
||||
* @run main/othervm/timeout=480 CheckUnmarshalOnStopThread
|
||||
*/
|
||||
|
||||
import java.rmi.*;
|
||||
import java.rmi.server.*;
|
||||
import java.io.*;
|
||||
import java.rmi.registry.*;
|
||||
|
||||
/**
|
||||
* Description for 4118600:
|
||||
*
|
||||
* If an rmi call thread is stopped while unmarshalling a return
|
||||
* value), java.lang.ThreadDeath will be thrown during
|
||||
* UnicastRef.invoke(...). If rmi handles the Error properly, the
|
||||
* remote method connection will not be reused. Otherwise the
|
||||
* connection can be freed and reused in a corrupted state, which will
|
||||
* lead to the throwing of an UnmarshalException the next time the
|
||||
* connection is used.
|
||||
*
|
||||
* To test RMI Error handling, the test invokes the remote call,
|
||||
* getPoisonPill, a number of times. This method returns an object
|
||||
* which throws an Error on return value deserialization (from its
|
||||
* readObject method). If RMI handles the error correctly, another
|
||||
* remote call, ping, should execute correctly (i.e. with no
|
||||
* exceptions). The test fails if the ping method throws an
|
||||
* UnmarshalException.
|
||||
*
|
||||
* The old way that the test used to operate:
|
||||
*
|
||||
* Iterate a large number of times: each iteration spawns a thread
|
||||
* that makes multiple rmi calls, sleep for 10 milliseconds, then stop
|
||||
* the thread that is making the rmi calls (hopefully during return
|
||||
* value Unmarshalling).
|
||||
*
|
||||
* Count the number of UnmarshalExceptions that occur during test
|
||||
* iterations. If this number is > 10, then the test fails.
|
||||
*
|
||||
* Note: Even if rmi is catching java.lang.ThreadDeath properly, other
|
||||
* types of exceptions (often related to monitor state, etc.) can
|
||||
* occur. This test is only written to track UnmarshalExceptions;
|
||||
* success/failure does not depend on other types of problems.
|
||||
*
|
||||
* Description for 4177704:
|
||||
*
|
||||
* Similar situation as for 4177704 except that instead of just
|
||||
* ensuring that RMI properly handles Errors, the second part of the
|
||||
* test ensures that RMI deals with RuntimeExceptions correctly.
|
||||
*
|
||||
* Test also ensures that call connections are freed without reuse
|
||||
* when RuntimeExceptions are thrown during the marshalling of call
|
||||
* parameters. An object that throws a RuntimeException in its
|
||||
* writeObject method helps to carry out this part of the test.
|
||||
*/
|
||||
public class CheckUnmarshalOnStopThread
|
||||
extends UnicastRemoteObject
|
||||
implements CheckUnmarshal
|
||||
{
|
||||
final static int RUNTIME_PILL = 1;
|
||||
public static int typeToThrow = 0;
|
||||
|
||||
/*
|
||||
* remote object implementation
|
||||
*/
|
||||
|
||||
CheckUnmarshalOnStopThread() throws RemoteException { }
|
||||
|
||||
public PoisonPill getPoisonPill() throws RemoteException {
|
||||
return new PoisonPill(new Integer(0));
|
||||
}
|
||||
|
||||
public Object ping() throws RemoteException {
|
||||
return (Object) new Integer(0);
|
||||
}
|
||||
|
||||
public void passRuntimeExceptionParameter(
|
||||
RuntimeExceptionParameter rep) throws RemoteException
|
||||
{
|
||||
// will never be called
|
||||
}
|
||||
|
||||
public static void main(String [] args) {
|
||||
|
||||
Object dummy = new Object();
|
||||
CheckUnmarshal cu = null;
|
||||
CheckUnmarshalOnStopThread cuonst = null;
|
||||
|
||||
System.err.println("\nregression test for bugs: " +
|
||||
"4118600 and 4177704\n");
|
||||
|
||||
try {
|
||||
cuonst = new CheckUnmarshalOnStopThread();
|
||||
cu = (CheckUnmarshal) UnicastRemoteObject.toStub(cuonst);
|
||||
|
||||
// make sure that RMI will free connections appropriately
|
||||
// under several situations:
|
||||
|
||||
// when Errors are thrown during parameter unmarshalling
|
||||
System.err.println("testing to see if RMI will handle errors");
|
||||
ensureConnectionsAreFreed(cu, true);
|
||||
|
||||
// when RuntimeExceptions are thrown during parameter unmarshalling
|
||||
System.err.println("testing to see if RMI will handle " +
|
||||
"runtime exceptions");
|
||||
typeToThrow = RUNTIME_PILL;
|
||||
ensureConnectionsAreFreed(cu, true);
|
||||
|
||||
// when RuntimeExceptions are thrown during parameter marshalling
|
||||
System.err.println("testing to see if RMI will handle " +
|
||||
"runtime exceptions thrown during " +
|
||||
"parameter marshalling");
|
||||
ensureConnectionsAreFreed(cu, false);
|
||||
|
||||
System.err.println
|
||||
("\nsuccess: CheckUnmarshalOnStopThread test passed ");
|
||||
|
||||
} catch (Exception e) {
|
||||
TestLibrary.bomb(e);
|
||||
} finally {
|
||||
cu = null;
|
||||
deactivate(cuonst);
|
||||
}
|
||||
}
|
||||
|
||||
static void ensureConnectionsAreFreed(CheckUnmarshal cu, boolean getPill)
|
||||
throws Exception
|
||||
{
|
||||
// invoke a remote call that will corrupt a call connection
|
||||
// that will not be freed (if the bug is not fixed)
|
||||
|
||||
for (int i = 0 ; i < 250 ; i++) {
|
||||
try {
|
||||
Object test = cu.ping();
|
||||
if (getPill) {
|
||||
cu.getPoisonPill();
|
||||
} else {
|
||||
cu.passRuntimeExceptionParameter(
|
||||
new RuntimeExceptionParameter());
|
||||
}
|
||||
} catch (Error e) {
|
||||
// expect an Error from call unmarshalling, ignore it
|
||||
} catch (RuntimeException e) {
|
||||
// " RuntimeException "
|
||||
}
|
||||
}
|
||||
|
||||
System.err.println("remote calls passed, received no " +
|
||||
"unmarshal exceptions\n\n");
|
||||
}
|
||||
|
||||
static void deactivate(RemoteServer r) {
|
||||
// make sure that the object goes away
|
||||
try {
|
||||
System.err.println("deactivating object.");
|
||||
UnicastRemoteObject.unexportObject(r, true);
|
||||
} catch (Exception e) {
|
||||
e.getMessage();
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2008, 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.
|
||||
*/
|
||||
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class CheckUnmarshalOnStopThread_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements CheckUnmarshal, java.rmi.Remote
|
||||
{
|
||||
private static final java.rmi.server.Operation[] operations = {
|
||||
new java.rmi.server.Operation("PoisonPill getPoisonPill()"),
|
||||
new java.rmi.server.Operation("void passRuntimeExceptionParameter(RuntimeExceptionParameter)"),
|
||||
new java.rmi.server.Operation("java.lang.Object ping()")
|
||||
};
|
||||
|
||||
private static final long interfaceHash = -5923540687975666490L;
|
||||
|
||||
private static final long serialVersionUID = 2;
|
||||
|
||||
private static boolean useNewInvoke;
|
||||
private static java.lang.reflect.Method $method_getPoisonPill_0;
|
||||
private static java.lang.reflect.Method $method_passRuntimeExceptionParameter_1;
|
||||
private static java.lang.reflect.Method $method_ping_2;
|
||||
|
||||
static {
|
||||
try {
|
||||
java.rmi.server.RemoteRef.class.getMethod("invoke",
|
||||
new java.lang.Class[] {
|
||||
java.rmi.Remote.class,
|
||||
java.lang.reflect.Method.class,
|
||||
java.lang.Object[].class,
|
||||
long.class
|
||||
});
|
||||
useNewInvoke = true;
|
||||
$method_getPoisonPill_0 = CheckUnmarshal.class.getMethod("getPoisonPill", new java.lang.Class[] {});
|
||||
$method_passRuntimeExceptionParameter_1 = CheckUnmarshal.class.getMethod("passRuntimeExceptionParameter", new java.lang.Class[] {RuntimeExceptionParameter.class});
|
||||
$method_ping_2 = CheckUnmarshal.class.getMethod("ping", new java.lang.Class[] {});
|
||||
} catch (java.lang.NoSuchMethodException e) {
|
||||
useNewInvoke = false;
|
||||
}
|
||||
}
|
||||
|
||||
// constructors
|
||||
public CheckUnmarshalOnStopThread_Stub() {
|
||||
super();
|
||||
}
|
||||
public CheckUnmarshalOnStopThread_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
// methods from remote interfaces
|
||||
|
||||
// implementation of getPoisonPill()
|
||||
public PoisonPill getPoisonPill()
|
||||
throws java.rmi.RemoteException
|
||||
{
|
||||
try {
|
||||
if (useNewInvoke) {
|
||||
Object $result = ref.invoke(this, $method_getPoisonPill_0, null, 5776441251039617360L);
|
||||
return ((PoisonPill) $result);
|
||||
} else {
|
||||
java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash);
|
||||
ref.invoke(call);
|
||||
PoisonPill $result;
|
||||
try {
|
||||
java.io.ObjectInput in = call.getInputStream();
|
||||
$result = (PoisonPill) in.readObject();
|
||||
} catch (java.io.IOException e) {
|
||||
throw new java.rmi.UnmarshalException("error unmarshalling return", e);
|
||||
} catch (java.lang.ClassNotFoundException e) {
|
||||
throw new java.rmi.UnmarshalException("error unmarshalling return", e);
|
||||
} finally {
|
||||
ref.done(call);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.rmi.RemoteException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of passRuntimeExceptionParameter(RuntimeExceptionParameter)
|
||||
public void passRuntimeExceptionParameter(RuntimeExceptionParameter $param_RuntimeExceptionParameter_1)
|
||||
throws java.rmi.RemoteException
|
||||
{
|
||||
try {
|
||||
if (useNewInvoke) {
|
||||
ref.invoke(this, $method_passRuntimeExceptionParameter_1, new java.lang.Object[] {$param_RuntimeExceptionParameter_1}, -4427599990679364365L);
|
||||
} else {
|
||||
java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 1, interfaceHash);
|
||||
try {
|
||||
java.io.ObjectOutput out = call.getOutputStream();
|
||||
out.writeObject($param_RuntimeExceptionParameter_1);
|
||||
} catch (java.io.IOException e) {
|
||||
throw new java.rmi.MarshalException("error marshalling arguments", e);
|
||||
}
|
||||
ref.invoke(call);
|
||||
ref.done(call);
|
||||
}
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.rmi.RemoteException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
|
||||
// implementation of ping()
|
||||
public java.lang.Object ping()
|
||||
throws java.rmi.RemoteException
|
||||
{
|
||||
try {
|
||||
if (useNewInvoke) {
|
||||
Object $result = ref.invoke(this, $method_ping_2, null, 7635508643486276040L);
|
||||
return ((java.lang.Object) $result);
|
||||
} else {
|
||||
java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 2, interfaceHash);
|
||||
ref.invoke(call);
|
||||
java.lang.Object $result;
|
||||
try {
|
||||
java.io.ObjectInput in = call.getInputStream();
|
||||
$result = (java.lang.Object) in.readObject();
|
||||
} catch (java.io.IOException e) {
|
||||
throw new java.rmi.UnmarshalException("error unmarshalling return", e);
|
||||
} catch (java.lang.ClassNotFoundException e) {
|
||||
throw new java.rmi.UnmarshalException("error unmarshalling return", e);
|
||||
} finally {
|
||||
ref.done(call);
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.rmi.RemoteException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2008, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Class whos readObject method throws a RuntimeException or an
|
||||
* Error. Helps to make sure that the UnicastRef.invoke method
|
||||
* handles ThreadDeath errors correctly (frees relevant corrupted
|
||||
* call connections with out reuse).
|
||||
*/
|
||||
public class PoisonPill implements Serializable {
|
||||
Integer corruptTheCallStream = null;
|
||||
|
||||
PoisonPill(Integer corruptTheCallStream) {
|
||||
this.corruptTheCallStream = corruptTheCallStream;
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in)
|
||||
throws IOException
|
||||
{
|
||||
if (CheckUnmarshalOnStopThread.typeToThrow !=
|
||||
CheckUnmarshalOnStopThread.RUNTIME_PILL) {
|
||||
|
||||
throw new Error("Wrote a test object whos readObject " +
|
||||
"method always throws an Error");
|
||||
|
||||
} else {
|
||||
|
||||
throw new RuntimeException("Wrote a test object " +
|
||||
"whos readObject method " +
|
||||
"always throws a RuntimeException");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,43 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2008, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* Class to help verify that RMI handles RuntimeExceptions on parameter
|
||||
* marshalling correctly.
|
||||
*/
|
||||
class RuntimeExceptionParameter implements Serializable {
|
||||
private void writeObject(ObjectOutputStream out)
|
||||
throws IOException
|
||||
{
|
||||
throw new RuntimeException("wrote a parameter whos writeObject " +
|
||||
"method always throws a RuntimeException"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,125 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 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 4164696
|
||||
* @summary The local garbage collector needs to inspect a client VM's heap
|
||||
* often enough (even if the VM is idle) to detect unreachable live remote
|
||||
* references, so that their server VMs can be informed that the client VM
|
||||
* is no longer holding a reference; this facilitates the server VM invoking
|
||||
* the remote object's unreferenced() method (if present), garbage collecting
|
||||
* the remote object, and allowing the server VM to exit. This test focuses
|
||||
* on the unreferenced() method being invoked: it tests that the callback
|
||||
* method will be invoked within a reasonable time after the remote object is
|
||||
* no longer remotely reachable.
|
||||
* @author Peter Jones
|
||||
*
|
||||
* @library ../../../testlibrary
|
||||
* @modules java.rmi/sun.rmi.registry
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary FiniteGCLatency_Stub
|
||||
* @run main/othervm/timeout=120 FiniteGCLatency
|
||||
*/
|
||||
|
||||
import java.rmi.*;
|
||||
import java.rmi.registry.*;
|
||||
import java.rmi.server.*;
|
||||
|
||||
public class FiniteGCLatency implements Remote, Unreferenced {
|
||||
|
||||
private final static String BINDING = "FiniteGCLatency";
|
||||
private final static long GC_INTERVAL = 6000;
|
||||
private final static long TIMEOUT = 50000;
|
||||
|
||||
private Object lock = new Object();
|
||||
private boolean unreferencedInvoked = false;
|
||||
|
||||
public void unreferenced() {
|
||||
System.err.println("unreferenced() method invoked");
|
||||
synchronized (lock) {
|
||||
unreferencedInvoked = true;
|
||||
lock.notify();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
System.err.println("\nRegression test for bug 4164696\n");
|
||||
|
||||
/*
|
||||
* Set the interval that RMI will request for GC latency (before RMI
|
||||
* gets initialized and this property is read) to an unrealistically
|
||||
* small value, so that this test shouldn't have to wait too long.
|
||||
*/
|
||||
System.setProperty("sun.rmi.dgc.client.gcInterval",
|
||||
String.valueOf(GC_INTERVAL));
|
||||
|
||||
FiniteGCLatency obj = new FiniteGCLatency();
|
||||
|
||||
try {
|
||||
UnicastRemoteObject.exportObject(obj);
|
||||
System.err.println("exported remote object");
|
||||
Registry registry1 = TestLibrary.createRegistryOnEphemeralPort();
|
||||
int port = TestLibrary.getRegistryPort(registry1);
|
||||
System.err.println("created registry");
|
||||
|
||||
Registry registry = LocateRegistry.getRegistry("", port);
|
||||
registry.bind(BINDING, obj);
|
||||
System.err.println("bound remote object in registry");
|
||||
|
||||
synchronized (obj.lock) {
|
||||
registry.unbind(BINDING);
|
||||
System.err.println("unbound remote object from registry; " +
|
||||
"waiting for unreferenced() callback...");
|
||||
obj.lock.wait(TIMEOUT);
|
||||
|
||||
if (obj.unreferencedInvoked) {
|
||||
System.err.println("TEST PASSED: unreferenced() invoked");
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: unrefereced() not invoked after " +
|
||||
((double) TIMEOUT / 1000.0) + " seconds");
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
if (e instanceof RuntimeException) {
|
||||
throw (RuntimeException) e;
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: unexpected exception: " + e.toString());
|
||||
}
|
||||
} finally {
|
||||
/*
|
||||
* When all is said and done, try to unexport the remote object
|
||||
* so that the VM has a chance to exit.
|
||||
*/
|
||||
try {
|
||||
UnicastRemoteObject.unexportObject(obj, true);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2008, 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.
|
||||
*/
|
||||
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class FiniteGCLatency_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements java.rmi.Remote
|
||||
{
|
||||
private static final long serialVersionUID = 2;
|
||||
|
||||
// constructors
|
||||
public FiniteGCLatency_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2026, 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 4285878
|
||||
* @summary When the "java.rmi.dgc.leaseValue" system property is set to a
|
||||
* value much lower than its default (10 minutes), then the server-side
|
||||
* user-visible detection of DGC lease expiration-- in the form of
|
||||
* Unreferenced.unreferenced() invocations and possibly even local garbage
|
||||
* collection (including weak reference notification, finalization, etc.)--
|
||||
* may be delayed longer than expected. While this is not a spec violation
|
||||
* (because there are no timeliness guarantees for any of these garbage
|
||||
* collection-related events), the user might expect that an unreferenced()
|
||||
* invocation for an object whose last client has terminated abnormally
|
||||
* should occur on relatively the same time order as the lease value
|
||||
* granted.
|
||||
*
|
||||
* @library ../../../testlibrary
|
||||
* @modules java.rmi/sun.rmi.registry
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary JavaVM LeaseCheckInterval_Stub SelfTerminator
|
||||
* @run main/othervm LeaseCheckInterval
|
||||
*/
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.registry.Registry;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
import java.rmi.server.Unreferenced;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
public class LeaseCheckInterval implements Remote, Unreferenced {
|
||||
|
||||
public static final String BINDING = "LeaseCheckInterval";
|
||||
// lease expiry time (milliseconds)
|
||||
private static final long LEASE_VALUE = 10000;
|
||||
// the maximum allowed duration between the lease expiration and
|
||||
// the Unreferenced.unreferenced() callback method to be invoked
|
||||
private static final Duration EXPECTED_MAX_DURATION = Duration.ofMinutes(1);
|
||||
|
||||
// will be counted down when Unreferenced.unreferenced() is invoked
|
||||
private static final CountDownLatch callbackInvocationLatch = new CountDownLatch(1);
|
||||
|
||||
@Override
|
||||
public void unreferenced() {
|
||||
System.err.println("[" + Instant.now() + "] unreferenced() method invoked");
|
||||
callbackInvocationLatch.countDown();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
/*
|
||||
* Set the duration of leases granted to a very small value, so that
|
||||
* we can test if expirations are detected in a roughly comparable
|
||||
* time.
|
||||
*/
|
||||
System.setProperty("java.rmi.dgc.leaseValue", String.valueOf(LEASE_VALUE));
|
||||
System.err.println("running test with java.rmi.dgc.leaseValue set to " + LEASE_VALUE);
|
||||
LeaseCheckInterval obj = new LeaseCheckInterval();
|
||||
JavaVM jvm = null;
|
||||
|
||||
try {
|
||||
UnicastRemoteObject.exportObject(obj);
|
||||
System.err.println("exported remote object");
|
||||
|
||||
Registry localRegistry = TestLibrary.createRegistryOnEphemeralPort();
|
||||
int registryPort = TestLibrary.getRegistryPort(localRegistry);
|
||||
System.err.println("created local registry on port " + registryPort);
|
||||
|
||||
localRegistry.bind(BINDING, obj);
|
||||
System.err.println("bound remote object in local registry");
|
||||
|
||||
System.err.println("starting remote client VM...");
|
||||
jvm = new JavaVM("SelfTerminator", "-Drmi.registry.port=" + registryPort, "");
|
||||
// launch the self terminating java application which will lookup
|
||||
// the bound object (thus creating a lease) and then terminate itself (thus
|
||||
// creating the condition for a lease expiry).
|
||||
jvm.start();
|
||||
final Instant startTime = Instant.now();
|
||||
System.err.println("waiting for SelfTerminator process to complete");
|
||||
final int exitCode = jvm.waitFor();
|
||||
if (exitCode != 0) {
|
||||
throw new AssertionError("SelfTerminator process exited with" +
|
||||
" a non-zero exit code: " + exitCode);
|
||||
}
|
||||
System.err.println("SelfTerminator process completed in "
|
||||
+ Duration.between(startTime, Instant.now())
|
||||
+ ", now waiting for Unreferenced.unreferenced() callback to be invoked");
|
||||
callbackInvocationLatch.await();
|
||||
final Instant waitEndedAt = Instant.now();
|
||||
final Duration waitDuration = assertWithinExpectedTimeLimit(waitEndedAt, startTime);
|
||||
System.err.println("TEST PASSED: unreferenced() invoked in timely" +
|
||||
" fashion (duration=" + waitDuration + ")");
|
||||
} finally {
|
||||
if (jvm != null) {
|
||||
jvm.destroy();
|
||||
}
|
||||
/*
|
||||
* When all is said and done, try to unexport the remote object
|
||||
* so that the VM has a chance to exit.
|
||||
*/
|
||||
try {
|
||||
UnicastRemoteObject.unexportObject(obj, true);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Verifies that the duration between the lease expiration and the callback
|
||||
* invocation is within the expected limit. Throws an exception if the wait
|
||||
* duration is larger than expected limit, else returns the actual wait duration.
|
||||
*/
|
||||
private static Duration assertWithinExpectedTimeLimit(final Instant waitEndedAt,
|
||||
final Instant terminationStartedAt) {
|
||||
|
||||
final Duration waitDuration = Duration.between(terminationStartedAt, waitEndedAt);
|
||||
System.out.println("wait completed in " + waitDuration);
|
||||
if (waitDuration.compareTo(EXPECTED_MAX_DURATION) > 0) {
|
||||
throw new RuntimeException("Took unexpectedly long (duration=" +
|
||||
waitDuration + ") to invoke Unreferenced.unreferenced()," +
|
||||
" expected max duration=" + EXPECTED_MAX_DURATION);
|
||||
}
|
||||
return waitDuration;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2008, 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.
|
||||
*/
|
||||
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class LeaseCheckInterval_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements java.rmi.Remote
|
||||
{
|
||||
private static final long serialVersionUID = 2;
|
||||
|
||||
// constructors
|
||||
public LeaseCheckInterval_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2026, 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.
|
||||
*/
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.registry.LocateRegistry;
|
||||
import java.rmi.registry.Registry;
|
||||
import java.time.Instant;
|
||||
|
||||
public class SelfTerminator {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
try {
|
||||
log("main() invoked");
|
||||
int registryPort =
|
||||
Integer.parseInt(System.getProperty("rmi.registry.port"));
|
||||
Registry registry =
|
||||
LocateRegistry.getRegistry("", registryPort);
|
||||
Remote stub = registry.lookup(LeaseCheckInterval.BINDING);
|
||||
log("looked up binding, now terminating the process");
|
||||
Runtime.getRuntime().halt(0);
|
||||
} catch (Throwable t) {
|
||||
log("failure: " + t);
|
||||
t.printStackTrace();
|
||||
throw t; // propagate any failures and fail the process
|
||||
}
|
||||
}
|
||||
|
||||
private static void log(final String message) {
|
||||
final Instant now = Instant.now();
|
||||
System.err.println("[" + now + "] " + SelfTerminator.class.getName() + " - " + message);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* Copyright (c) 2000, 2012, 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 When an object is retrieved from a MarshalledObject, callbacks
|
||||
* that were registered by objects in the graph for execution when the
|
||||
* unmarshalling is done should get executed. This is verified by way of
|
||||
* an exported object's stub getting unmarshalled, and then garbage
|
||||
* collected, in which case the impl's unreferenced() method should get
|
||||
* invoked.
|
||||
* @author Peter Jones
|
||||
*
|
||||
* @build MarshalledObjectGet_Stub
|
||||
* @run main/othervm/timeout=120 MarshalledObjectGet
|
||||
*/
|
||||
|
||||
import java.rmi.MarshalledObject;
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
import java.rmi.server.Unreferenced;
|
||||
|
||||
public class MarshalledObjectGet implements Remote, Unreferenced {
|
||||
|
||||
private static final String BINDING = "MarshalledObjectGet";
|
||||
private static final long GC_INTERVAL = 6000;
|
||||
private static final long TIMEOUT = 50000;
|
||||
|
||||
private Object lock = new Object();
|
||||
private boolean unreferencedInvoked;
|
||||
|
||||
public void unreferenced() {
|
||||
System.err.println("unreferenced() method invoked");
|
||||
synchronized (lock) {
|
||||
unreferencedInvoked = true;
|
||||
lock.notify();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
System.err.println(
|
||||
"\nTest to verify correction interaction of " +
|
||||
"MarshalledObject.get and DGC registration\n");
|
||||
|
||||
/*
|
||||
* Set the interval that RMI will request for GC latency (before RMI
|
||||
* gets initialized and this property is read) to an unrealistically
|
||||
* small value, so that this test shouldn't have to wait too long.
|
||||
*/
|
||||
System.setProperty("sun.rmi.dgc.client.gcInterval",
|
||||
String.valueOf(GC_INTERVAL));
|
||||
|
||||
MarshalledObjectGet obj = new MarshalledObjectGet();
|
||||
|
||||
try {
|
||||
Remote stub = UnicastRemoteObject.exportObject(obj);
|
||||
System.err.println("exported remote object");
|
||||
|
||||
MarshalledObject mobj = new MarshalledObject(stub);
|
||||
Remote unmarshalledStub = (Remote) mobj.get();
|
||||
System.err.println("unmarshalled stub from marshalled object");
|
||||
|
||||
synchronized (obj.lock) {
|
||||
obj.unreferencedInvoked = false;
|
||||
|
||||
unmarshalledStub = null;
|
||||
System.gc();
|
||||
System.err.println("cleared unmarshalled stub");
|
||||
System.err.println("waiting for unreferenced() callback " +
|
||||
"(SHOULD happen)...");
|
||||
obj.lock.wait(TIMEOUT);
|
||||
|
||||
if (obj.unreferencedInvoked) {
|
||||
// TEST PASSED
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: unrefereced() not invoked after " +
|
||||
((double) TIMEOUT / 1000.0) + " seconds");
|
||||
}
|
||||
}
|
||||
|
||||
System.err.println("TEST PASSED");
|
||||
|
||||
} catch (Exception e) {
|
||||
if (e instanceof RuntimeException) {
|
||||
throw (RuntimeException) e;
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: unexpected exception: " + e.toString());
|
||||
}
|
||||
} finally {
|
||||
if (obj != null) {
|
||||
try {
|
||||
UnicastRemoteObject.unexportObject(obj, true);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2008, 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.
|
||||
*/
|
||||
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class MarshalledObjectGet_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements java.rmi.Remote
|
||||
{
|
||||
private static final long serialVersionUID = 2;
|
||||
|
||||
// constructors
|
||||
public MarshalledObjectGet_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,186 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2024, 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 4171278
|
||||
* @summary A remote object's unreferenced() method should be invoked with the
|
||||
* context class loader set to the same context class loader that would be set
|
||||
* when remote calls for that object are being executed: the object's class's
|
||||
* class loader, or the context class loader set when the remote object was
|
||||
* exported, if it is a child of the remote object's class loader.
|
||||
* @author Peter Jones
|
||||
*
|
||||
* @bug 4214123
|
||||
* @summary Unreferenced.unreferenced(...) threads should run in the nonSystem group.
|
||||
* To complete the fix for, 4182104, RMI unreferenced threads should also
|
||||
* run in the nonSystem so that they do not need permissions to modify the
|
||||
* system thread group.
|
||||
*
|
||||
* @author Laird Dornin
|
||||
*
|
||||
* @library ../../../testlibrary
|
||||
* @modules java.rmi/sun.rmi.registry
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary UnreferencedContext_Stub
|
||||
* @run main/othervm/timeout=120 UnreferencedContext
|
||||
*/
|
||||
|
||||
import java.net.*;
|
||||
import java.rmi.*;
|
||||
import java.rmi.registry.*;
|
||||
import java.rmi.server.*;
|
||||
|
||||
public class UnreferencedContext implements Remote, Unreferenced, Runnable {
|
||||
|
||||
private final static String BINDING = "UnreferencedContext";
|
||||
private final static long GC_INTERVAL = 6000;
|
||||
private final static long TIMEOUT = 60000;
|
||||
|
||||
private Object lock = new Object();
|
||||
private boolean unreferencedInvoked = false;
|
||||
private ClassLoader unreferencedContext;
|
||||
|
||||
public void run() {
|
||||
System.err.println("unreferenced method created thread succesfully");
|
||||
}
|
||||
|
||||
public void unreferenced() {
|
||||
// exercise functionality prohibited by 4214123
|
||||
(new Thread(this)).start();
|
||||
|
||||
System.err.println("unreferenced() method invoked");
|
||||
synchronized (lock) {
|
||||
unreferencedInvoked = true;
|
||||
unreferencedContext =
|
||||
Thread.currentThread().getContextClassLoader();
|
||||
lock.notify();
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
|
||||
System.err.println("\nRegression test for bug 4171278\n");
|
||||
|
||||
/*
|
||||
* Set the interval that RMI will request for GC latency (before RMI
|
||||
* gets initialized and this property is read) to an unrealistically
|
||||
* small value, so that this test shouldn't have to wait too long.
|
||||
*/
|
||||
System.setProperty("sun.rmi.dgc.client.gcInterval",
|
||||
String.valueOf(GC_INTERVAL));
|
||||
|
||||
UnreferencedContext obj = new UnreferencedContext();
|
||||
|
||||
try {
|
||||
/*
|
||||
* This little trick is necessary to make sure that the RMI server
|
||||
* threads for objects created on the default port get created
|
||||
* before we set our special context class loader, so that they
|
||||
* don't *accidentally* inherit it when making the unreferenced()
|
||||
* callback.
|
||||
*/
|
||||
UnicastRemoteObject.exportObject(obj);
|
||||
UnicastRemoteObject.unexportObject(obj, true);
|
||||
|
||||
/*
|
||||
* Now create special context class loader before exporting the
|
||||
* remote object for real, so that it should be set when the
|
||||
* object's unreferenced() method is called.
|
||||
*/
|
||||
ClassLoader intendedContext = new URLClassLoader(new URL[0]);
|
||||
Thread.currentThread().setContextClassLoader(intendedContext);
|
||||
System.err.println(
|
||||
"created and set intended context class loader: " +
|
||||
intendedContext);
|
||||
|
||||
UnicastRemoteObject.exportObject(obj);
|
||||
System.err.println("exported remote object");
|
||||
|
||||
Registry registry1 = TestLibrary.createRegistryOnEphemeralPort();
|
||||
int port = TestLibrary.getRegistryPort(registry1);
|
||||
System.err.println("created registry");
|
||||
|
||||
Registry registry = LocateRegistry.getRegistry("", port);
|
||||
registry.bind(BINDING, obj);
|
||||
System.err.println("bound remote object in registry");
|
||||
|
||||
synchronized (obj.lock) {
|
||||
registry.unbind(BINDING);
|
||||
System.err.println("unbound remote object from registry; " +
|
||||
"waiting for unreferenced() callback...");
|
||||
/*
|
||||
* This incantation seems sufficient to work around the
|
||||
* ramifications of 4164696, so that this test will actually
|
||||
* prove something useful about 1.2Beta4 or 1.2FCS before
|
||||
* 4171278 was fixed.
|
||||
*/
|
||||
for (int i = 0; i < 10; i++) {
|
||||
System.gc();
|
||||
obj.lock.wait(TIMEOUT / 10);
|
||||
if (obj.unreferencedInvoked) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (obj.unreferencedInvoked) {
|
||||
System.err.println(
|
||||
"invoked with context class loader: " +
|
||||
obj.unreferencedContext);
|
||||
|
||||
if (obj.unreferencedContext == intendedContext) {
|
||||
System.err.println(
|
||||
"TEST PASSED: unreferenced() invoked" +
|
||||
" with intended context class loader");
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: unreferenced() invoked" +
|
||||
" with incorrect context class loader");
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: unreferenced() not invoked after " +
|
||||
((double) TIMEOUT / 1000.0) + " seconds or unreferenced failed to create a thread");
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
if (e instanceof RuntimeException) {
|
||||
throw (RuntimeException) e;
|
||||
} else {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: unexpected exception: " + e.toString());
|
||||
}
|
||||
} finally {
|
||||
/*
|
||||
* When all is said and done, try to unexport the remote object
|
||||
* so that the VM has a chance to exit.
|
||||
*/
|
||||
try {
|
||||
UnicastRemoteObject.unexportObject(obj, true);
|
||||
} catch (RemoteException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2008, 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.
|
||||
*/
|
||||
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class UnreferencedContext_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements java.rmi.Remote
|
||||
{
|
||||
private static final long serialVersionUID = 2;
|
||||
|
||||
// constructors
|
||||
public UnreferencedContext_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
}
|
||||
121
test/jdk/java/rmi/server/clientStackTrace/ClientStackTrace.java
Normal file
121
test/jdk/java/rmi/server/clientStackTrace/ClientStackTrace.java
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2024, 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 4010355
|
||||
* @summary RemoteException should have server's stack trace
|
||||
*
|
||||
* @author Laird Dornin
|
||||
*
|
||||
* @library ../../testlibrary
|
||||
* @modules java.rmi/sun.rmi.registry
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary ClientStackTrace MyRemoteObject_Stub
|
||||
* @run main/othervm/timeout=120 ClientStackTrace
|
||||
*/
|
||||
|
||||
/*
|
||||
* This test ensures that the stack trace in a caught server side
|
||||
* remote exception contains the string "exceptionReceivedFromServer".
|
||||
*/
|
||||
|
||||
import java.rmi.*;
|
||||
import java.rmi.server.*;
|
||||
import sun.rmi.transport.StreamRemoteCall;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
|
||||
interface MyRemoteInterface extends Remote {
|
||||
void ping() throws RemoteException;
|
||||
}
|
||||
|
||||
class MyRemoteObject extends UnicastRemoteObject
|
||||
implements MyRemoteInterface {
|
||||
|
||||
public MyRemoteObject () throws RemoteException {}
|
||||
|
||||
public void ping () throws RemoteException {
|
||||
throw new RemoteException("This is a test remote exception");
|
||||
}
|
||||
}
|
||||
|
||||
public class ClientStackTrace {
|
||||
Object dummy = new Object();
|
||||
|
||||
public static void main(String[] args) {
|
||||
Object dummy = new Object();
|
||||
MyRemoteObject myRobj = null;
|
||||
MyRemoteInterface myStub = null;
|
||||
|
||||
try {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
PrintStream ps = new PrintStream(bos);
|
||||
|
||||
System.err.println("\nRegression test for bug 4010355\n");
|
||||
|
||||
myRobj = new MyRemoteObject();
|
||||
|
||||
/* cause a remote exception to occur. */
|
||||
try {
|
||||
myStub = (MyRemoteInterface) RemoteObject.toStub(myRobj);
|
||||
myStub.ping();
|
||||
|
||||
} catch (RemoteException re) {
|
||||
re.printStackTrace(ps);
|
||||
String trace = bos.toString();
|
||||
|
||||
if (trace.indexOf("exceptionReceivedFromServer") <0 ) {
|
||||
throw new RuntimeException("No client stack trace on " +
|
||||
"thrown remote exception");
|
||||
} else {
|
||||
System.err.println("test passed with stack trace: " +
|
||||
trace);
|
||||
}
|
||||
}
|
||||
|
||||
deactivate(myRobj);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
System.err.println("test failed");
|
||||
throw new RuntimeException(e.getMessage());
|
||||
} finally {
|
||||
myRobj = null;
|
||||
myStub = null;
|
||||
}
|
||||
}
|
||||
|
||||
// make sure that the remote object goes away.
|
||||
static void deactivate(RemoteServer r) {
|
||||
// make sure that the object goes away
|
||||
try {
|
||||
System.err.println("deactivating object.");
|
||||
UnicastRemoteObject.unexportObject(r, true);
|
||||
} catch (Exception e) {
|
||||
e.getMessage();
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 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.
|
||||
*/
|
||||
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class MyRemoteObject_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements MyRemoteInterface, java.rmi.Remote
|
||||
{
|
||||
private static java.rmi.server.Operation[] operations = {
|
||||
new java.rmi.server.Operation("void ping()")
|
||||
};
|
||||
|
||||
private static final long interfaceHash = -8409781791984809394L;
|
||||
|
||||
private static final long serialVersionUID = 2;
|
||||
|
||||
private static boolean useNewInvoke;
|
||||
private static java.lang.reflect.Method $method_ping_0;
|
||||
|
||||
static {
|
||||
try {
|
||||
java.rmi.server.RemoteRef.class.getMethod("invoke",
|
||||
new java.lang.Class[] {
|
||||
java.rmi.Remote.class,
|
||||
java.lang.reflect.Method.class,
|
||||
java.lang.Object[].class,
|
||||
long.class
|
||||
});
|
||||
useNewInvoke = true;
|
||||
$method_ping_0 = MyRemoteInterface.class.getMethod("ping", new java.lang.Class[] {});
|
||||
} catch (java.lang.NoSuchMethodException e) {
|
||||
useNewInvoke = false;
|
||||
}
|
||||
}
|
||||
|
||||
// constructors
|
||||
public MyRemoteObject_Stub() {
|
||||
super();
|
||||
}
|
||||
public MyRemoteObject_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
// methods from remote interfaces
|
||||
|
||||
// implementation of ping()
|
||||
public void ping()
|
||||
throws java.rmi.RemoteException
|
||||
{
|
||||
try {
|
||||
if (useNewInvoke) {
|
||||
ref.invoke(this, $method_ping_0, null, 5866401369815527589L);
|
||||
} else {
|
||||
java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash);
|
||||
ref.invoke(call);
|
||||
ref.done(call);
|
||||
}
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.rmi.RemoteException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
102
test/jdk/java/rmi/server/getRemoteClass/GetRemoteClass.java
Normal file
102
test/jdk/java/rmi/server/getRemoteClass/GetRemoteClass.java
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 2012, 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 4152295
|
||||
* @summary trivial optimization in RemoteProxy.extendsRemote
|
||||
*
|
||||
* @author Laird Dornin
|
||||
*
|
||||
* @library ../../testlibrary
|
||||
* @modules java.rmi/sun.rmi.registry
|
||||
* java.rmi/sun.rmi.server:+open
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary
|
||||
* @run main/othervm GetRemoteClass
|
||||
*/
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.rmi.Remote;
|
||||
import sun.rmi.server.Util;
|
||||
import java.lang.reflect.*;
|
||||
|
||||
|
||||
/**
|
||||
* Simple test to make sure that Util.getRemoteClass throws
|
||||
* exception in proper circumstances. Pass two different classes, one
|
||||
* that extends Remote and one that only extends Serializable. Should
|
||||
* throw exception for Serializable.
|
||||
*/
|
||||
public class GetRemoteClass {
|
||||
public interface ExtendRemote extends Remote {
|
||||
}
|
||||
|
||||
public static class TestRemote implements ExtendRemote {
|
||||
}
|
||||
|
||||
public static class OnlySerializable implements Serializable {
|
||||
}
|
||||
|
||||
public static void main(String[] argv) {
|
||||
|
||||
System.err.println("\nregression test for 4152295\n");
|
||||
|
||||
Method utilGetRemoteClass = null;
|
||||
|
||||
try {
|
||||
/**
|
||||
* Use reflection to set access overrides so that the test
|
||||
* can call protected method, getRemoteClass
|
||||
*/
|
||||
Class[] args = new Class[1];
|
||||
args[0] = Class.class;
|
||||
utilGetRemoteClass =
|
||||
Util.class.getDeclaredMethod("getRemoteClass", args);
|
||||
utilGetRemoteClass.setAccessible(true);
|
||||
|
||||
// getRemoteClass can be invoked without exception
|
||||
utilGetRemoteClass.invoke
|
||||
(null , new Object [] {TestRemote.class});
|
||||
System.err.println("remote class flagged as remote");
|
||||
|
||||
ClassNotFoundException cnfe = null;
|
||||
try {
|
||||
// getRemoteClass can be invoked without exception
|
||||
utilGetRemoteClass.invoke
|
||||
(null , new Object [] {OnlySerializable.class});
|
||||
} catch (InvocationTargetException e) {
|
||||
System.err.println("got ClassNotFoundException; remote " +
|
||||
"class flagged as nonremote");
|
||||
cnfe = (ClassNotFoundException) e.getTargetException();
|
||||
}
|
||||
if (cnfe == null) {
|
||||
TestLibrary.bomb("Serializable class flagged as remote?");
|
||||
}
|
||||
|
||||
System.err.println("Test passed.");
|
||||
} catch (Exception e) {
|
||||
TestLibrary.bomb("Unexpected exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
64
test/jdk/java/rmi/server/serverStackTrace/Impl1_Skel.java
Normal file
64
test/jdk/java/rmi/server/serverStackTrace/Impl1_Skel.java
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 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.
|
||||
*/
|
||||
|
||||
// Skeleton class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class Impl1_Skel
|
||||
implements java.rmi.server.Skeleton
|
||||
{
|
||||
private static final java.rmi.server.Operation[] operations = {
|
||||
new java.rmi.server.Operation("void pong()")
|
||||
};
|
||||
|
||||
private static final long interfaceHash = -6081108852319377105L;
|
||||
|
||||
public java.rmi.server.Operation[] getOperations() {
|
||||
return (java.rmi.server.Operation[]) operations.clone();
|
||||
}
|
||||
|
||||
public void dispatch(java.rmi.Remote obj, java.rmi.server.RemoteCall call, int opnum, long hash)
|
||||
throws java.lang.Exception
|
||||
{
|
||||
if (hash != interfaceHash)
|
||||
throw new java.rmi.server.SkeletonMismatchException("interface hash mismatch");
|
||||
|
||||
Impl1 server = (Impl1) obj;
|
||||
switch (opnum) {
|
||||
case 0: // pong()
|
||||
{
|
||||
call.releaseInputStream();
|
||||
server.pong();
|
||||
try {
|
||||
call.getResultStream(true);
|
||||
} catch (java.io.IOException e) {
|
||||
throw new java.rmi.MarshalException("error marshalling return", e);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
throw new java.rmi.UnmarshalException("invalid method number");
|
||||
}
|
||||
}
|
||||
}
|
||||
65
test/jdk/java/rmi/server/serverStackTrace/Impl1_Stub.java
Normal file
65
test/jdk/java/rmi/server/serverStackTrace/Impl1_Stub.java
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 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.
|
||||
*/
|
||||
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class Impl1_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements Pong
|
||||
{
|
||||
private static final java.rmi.server.Operation[] operations = {
|
||||
new java.rmi.server.Operation("void pong()")
|
||||
};
|
||||
|
||||
private static final long interfaceHash = -6081108852319377105L;
|
||||
|
||||
// constructors
|
||||
public Impl1_Stub() {
|
||||
super();
|
||||
}
|
||||
public Impl1_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
// methods from remote interfaces
|
||||
|
||||
// implementation of pong()
|
||||
public void pong()
|
||||
throws PongException, java.rmi.RemoteException
|
||||
{
|
||||
try {
|
||||
java.rmi.server.RemoteCall call = ref.newCall((java.rmi.server.RemoteObject) this, operations, 0, interfaceHash);
|
||||
ref.invoke(call);
|
||||
ref.done(call);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.rmi.RemoteException e) {
|
||||
throw e;
|
||||
} catch (PongException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
67
test/jdk/java/rmi/server/serverStackTrace/Impl2_Stub.java
Normal file
67
test/jdk/java/rmi/server/serverStackTrace/Impl2_Stub.java
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 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.
|
||||
*/
|
||||
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class Impl2_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements Pong
|
||||
{
|
||||
private static final long serialVersionUID = 2;
|
||||
|
||||
private static java.lang.reflect.Method $method_pong_0;
|
||||
|
||||
static {
|
||||
try {
|
||||
$method_pong_0 = Pong.class.getMethod("pong", new java.lang.Class[] {});
|
||||
} catch (java.lang.NoSuchMethodException e) {
|
||||
throw new java.lang.NoSuchMethodError(
|
||||
"stub class initialization failed");
|
||||
}
|
||||
}
|
||||
|
||||
// constructors
|
||||
public Impl2_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
// methods from remote interfaces
|
||||
|
||||
// implementation of pong()
|
||||
public void pong()
|
||||
throws PongException, java.rmi.RemoteException
|
||||
{
|
||||
try {
|
||||
ref.invoke(this, $method_pong_0, null, -5941237182396893426L);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.rmi.RemoteException e) {
|
||||
throw e;
|
||||
} catch (PongException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
123
test/jdk/java/rmi/server/serverStackTrace/ServerStackTrace.java
Normal file
123
test/jdk/java/rmi/server/serverStackTrace/ServerStackTrace.java
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2012, 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 4010355
|
||||
* @summary When an exception is thrown by a remote method invocation, the
|
||||
* stack trace of the exception catchable by the client application should
|
||||
* comprise both the client-side trace as well as the server-side trace, as
|
||||
* serialized with the Throwable from the server.
|
||||
* @author Peter Jones
|
||||
*
|
||||
* @build ServerStackTrace ServerStackTrace_Stub
|
||||
* @run main/othervm ServerStackTrace
|
||||
*/
|
||||
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
|
||||
interface Ping extends Remote {
|
||||
void ping() throws PingException, RemoteException;
|
||||
}
|
||||
|
||||
class PingException extends Exception {
|
||||
}
|
||||
|
||||
public class ServerStackTrace implements Ping {
|
||||
|
||||
public void ping() throws PingException {
|
||||
__BAR__();
|
||||
}
|
||||
|
||||
private void __BAR__() throws PingException {
|
||||
throw new PingException();
|
||||
}
|
||||
|
||||
private static void __FOO__(Ping stub)
|
||||
throws PingException, RemoteException
|
||||
{
|
||||
stub.ping();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
System.err.println("\nRegression test for RFE 4010355\n");
|
||||
|
||||
ServerStackTrace impl = new ServerStackTrace();
|
||||
|
||||
try {
|
||||
Ping stub = (Ping) UnicastRemoteObject.exportObject(impl);
|
||||
|
||||
StackTraceElement[] remoteTrace;
|
||||
try {
|
||||
__FOO__(stub);
|
||||
throw new RuntimeException("TEST FAILED: no exception caught");
|
||||
} catch (PingException e) {
|
||||
System.err.println(
|
||||
"trace of exception thrown by remote call:");
|
||||
e.printStackTrace();
|
||||
System.err.println();
|
||||
remoteTrace = e.getStackTrace();
|
||||
}
|
||||
|
||||
int fooIndex = -1;
|
||||
int barIndex = -1;
|
||||
for (int i = 0; i < remoteTrace.length; i++) {
|
||||
StackTraceElement e = remoteTrace[i];
|
||||
if (e.getMethodName().equals("__FOO__")) {
|
||||
if (fooIndex != -1) {
|
||||
throw new RuntimeException("TEST FAILED: " +
|
||||
"trace contains more than one __FOO__");
|
||||
}
|
||||
fooIndex = i;
|
||||
} else if (e.getMethodName().equals("__BAR__")) {
|
||||
if (barIndex != -1) {
|
||||
throw new RuntimeException("TEST FAILED: " +
|
||||
"trace contains more than one __BAR__");
|
||||
}
|
||||
barIndex = i;
|
||||
}
|
||||
}
|
||||
if (fooIndex == -1) {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: trace lacks client-side method __FOO__");
|
||||
}
|
||||
if (barIndex == -1) {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: trace lacks server-side method __BAR__");
|
||||
}
|
||||
if (fooIndex < barIndex) {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: trace contains client-side method __FOO__ " +
|
||||
"before server-side method __BAR__");
|
||||
}
|
||||
System.err.println("TEST PASSED");
|
||||
} finally {
|
||||
try {
|
||||
UnicastRemoteObject.unexportObject(impl, true);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 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.
|
||||
*/
|
||||
|
||||
// Stub class generated by rmic, do not edit.
|
||||
// Contents subject to change without notice.
|
||||
|
||||
public final class ServerStackTrace_Stub
|
||||
extends java.rmi.server.RemoteStub
|
||||
implements Ping
|
||||
{
|
||||
private static final long serialVersionUID = 2;
|
||||
|
||||
private static java.lang.reflect.Method $method_ping_0;
|
||||
|
||||
static {
|
||||
try {
|
||||
$method_ping_0 = Ping.class.getMethod("ping", new java.lang.Class[] {});
|
||||
} catch (java.lang.NoSuchMethodException e) {
|
||||
throw new java.lang.NoSuchMethodError(
|
||||
"stub class initialization failed");
|
||||
}
|
||||
}
|
||||
|
||||
// constructors
|
||||
public ServerStackTrace_Stub(java.rmi.server.RemoteRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
// methods from remote interfaces
|
||||
|
||||
// implementation of ping()
|
||||
public void ping()
|
||||
throws PingException, java.rmi.RemoteException
|
||||
{
|
||||
try {
|
||||
ref.invoke(this, $method_ping_0, null, 5866401369815527589L);
|
||||
} catch (java.lang.RuntimeException e) {
|
||||
throw e;
|
||||
} catch (java.rmi.RemoteException e) {
|
||||
throw e;
|
||||
} catch (PingException e) {
|
||||
throw e;
|
||||
} catch (java.lang.Exception e) {
|
||||
throw new java.rmi.UnexpectedException("undeclared checked exception", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* Copyright (c) 2001, 2012, 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 4487532
|
||||
* @summary When the system property "sun.rmi.server.suppressStackTraces" is
|
||||
* set to boolean true, then the RMI runtime should take positive action to
|
||||
* counteract the new feature in 1.4 of an exception's stack trace being part
|
||||
* of its serialized form so that the server-side stack trace of an exception
|
||||
* that occurs during the execution of a remote method invocation gets
|
||||
* marshalled to the client. In most cases, this feature-- along with the
|
||||
* final fix to 4010355 to make the server-side stack trace data available
|
||||
* at the RMI client application level-- is highly desirable, but this system
|
||||
* property provides an opportunity to suppress the server-side stack trace
|
||||
* data of exceptions thrown by remote methods from being marshalled, perhaps
|
||||
* for reasons of performance or confidentiality requirements.
|
||||
* @author Peter Jones
|
||||
*
|
||||
* @build SuppressStackTraces Impl2_Stub Impl1_Stub Impl1_Skel
|
||||
* @run main/othervm SuppressStackTraces
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
import java.rmi.server.UnicastRemoteObject;
|
||||
import java.util.Arrays;
|
||||
|
||||
interface Pong extends Remote {
|
||||
void pong() throws PongException, RemoteException;
|
||||
}
|
||||
|
||||
class PongException extends Exception {
|
||||
private void readObject(ObjectInputStream in)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
in.defaultReadObject();
|
||||
|
||||
/*
|
||||
* Verify right at unmarshalling time that this exception instance
|
||||
* contains no stack trace data from the server (regardless of whether
|
||||
* or not it would be apparent at the RMI client application level).
|
||||
*/
|
||||
StackTraceElement[] trace = getStackTrace();
|
||||
if (trace.length > 0) {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: exception contained non-empty stack trace: " +
|
||||
Arrays.asList(trace));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// stub class generated with "rmic -v1.2 ..."
|
||||
class Impl2 implements Pong {
|
||||
public void pong() throws PongException { __BAR__(); }
|
||||
public void __BAR__() throws PongException { throw new PongException(); }
|
||||
}
|
||||
|
||||
// stub and skeleton classes generated with "rmic -v1.1 ..."
|
||||
class Impl1 implements Pong {
|
||||
public void pong() throws PongException { __BAR__(); }
|
||||
public void __BAR__() throws PongException { throw new PongException(); }
|
||||
}
|
||||
|
||||
public class SuppressStackTraces {
|
||||
|
||||
private static void __FOO__(Pong stub)
|
||||
throws PongException, RemoteException
|
||||
{
|
||||
stub.pong();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
|
||||
System.err.println("\nRegression test for RFE 4487532\n");
|
||||
|
||||
System.setProperty("sun.rmi.server.suppressStackTraces", "true");
|
||||
|
||||
Remote impl2 = new Impl2();
|
||||
Remote impl1 = new Impl1();
|
||||
|
||||
try {
|
||||
/*
|
||||
* Verify behavior for both -v1.1 and -v1.2 stub protocols.
|
||||
*/
|
||||
verifySuppression((Pong) UnicastRemoteObject.exportObject(impl2));
|
||||
verifySuppression((Pong) UnicastRemoteObject.exportObject(impl1));
|
||||
|
||||
System.err.println(
|
||||
"TEST PASSED (server-side stack trace data suppressed)");
|
||||
} finally {
|
||||
try {
|
||||
UnicastRemoteObject.unexportObject(impl1, true);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
try {
|
||||
UnicastRemoteObject.unexportObject(impl2, true);
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void verifySuppression(Pong stub) throws Exception {
|
||||
System.err.println("testing stub for exported object: " + stub);
|
||||
|
||||
StackTraceElement[] remoteTrace;
|
||||
try {
|
||||
__FOO__(stub);
|
||||
throw new RuntimeException("TEST FAILED: no exception caught");
|
||||
} catch (PongException e) {
|
||||
System.err.println(
|
||||
"trace of exception thrown by remote call:");
|
||||
e.printStackTrace();
|
||||
System.err.println();
|
||||
remoteTrace = e.getStackTrace();
|
||||
}
|
||||
|
||||
int fooIndex = -1;
|
||||
for (int i = 0; i < remoteTrace.length; i++) {
|
||||
StackTraceElement e = remoteTrace[i];
|
||||
if (e.getMethodName().equals("__FOO__")) {
|
||||
if (fooIndex != -1) {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: trace contains more than one __FOO__");
|
||||
}
|
||||
fooIndex = i;
|
||||
} else if (e.getMethodName().equals("__BAR__")) {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: trace contains __BAR__");
|
||||
}
|
||||
}
|
||||
if (fooIndex == -1) {
|
||||
throw new RuntimeException(
|
||||
"TEST FAILED: trace lacks client-side method __FOO__");
|
||||
}
|
||||
}
|
||||
}
|
||||
32
test/jdk/java/rmi/server/useCustomRef/Ping.java
Normal file
32
test/jdk/java/rmi/server/useCustomRef/Ping.java
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* Copyright (c) 1999, 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
import java.rmi.Remote;
|
||||
import java.rmi.RemoteException;
|
||||
interface Ping extends Remote {
|
||||
public void ping() throws RemoteException;
|
||||
public void receiveAndPing(Ping p) throws RemoteException;
|
||||
}
|
||||
219
test/jdk/java/rmi/server/useCustomRef/UseCustomRef.java
Normal file
219
test/jdk/java/rmi/server/useCustomRef/UseCustomRef.java
Normal file
|
|
@ -0,0 +1,219 @@
|
|||
/*
|
||||
* Copyright (c) 1998, 2024, 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 4155894
|
||||
*
|
||||
* @summary remote references can't be downloaded
|
||||
* @author Ann Wollrath
|
||||
*
|
||||
* test currently needs RMISecurityManager because of
|
||||
* 4180392
|
||||
*
|
||||
* @library ../../testlibrary
|
||||
* @modules java.rmi/sun.rmi.registry
|
||||
* java.rmi/sun.rmi.server
|
||||
* java.rmi/sun.rmi.transport
|
||||
* java.rmi/sun.rmi.transport.tcp
|
||||
* @build TestLibrary Ping UseCustomRef_Stub UseCustomRef_Skel
|
||||
* @run main/othervm/timeout=120 UseCustomRef
|
||||
*
|
||||
* This test was failing to run because the synthetic access
|
||||
* control context used by the application class loader to find and define
|
||||
* CustomServerRef does not have accessClassInPackage.sun.rmi.server runtime
|
||||
* permission necessary to load its superclass sun.rmi.server.UnicastServerRef,
|
||||
* even though this test's code is granted that permission in its policy file.
|
||||
* That bug number is 4256530
|
||||
*/
|
||||
|
||||
import java.io.*;
|
||||
import java.rmi.*;
|
||||
import java.rmi.server.*;
|
||||
import java.rmi.registry.*;
|
||||
import sun.rmi.transport.LiveRef;
|
||||
|
||||
public class UseCustomRef
|
||||
extends RemoteServer
|
||||
implements Ping
|
||||
{
|
||||
|
||||
public UseCustomRef() throws RemoteException {
|
||||
exportObject();
|
||||
}
|
||||
|
||||
public void exportObject() throws RemoteException {
|
||||
ref = new CustomServerRef(new LiveRef(0));
|
||||
((ServerRef) ref).exportObject(this, null);
|
||||
}
|
||||
|
||||
public RemoteRef getRef() { return ref; }
|
||||
|
||||
public void ping() {}
|
||||
|
||||
public void receiveAndPing(Ping p) throws RemoteException {
|
||||
p.ping();
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
Ping obj = null;
|
||||
Registry registry = null;
|
||||
|
||||
try {
|
||||
/*
|
||||
* create registry
|
||||
*/
|
||||
|
||||
System.err.println("creating Registry...");
|
||||
|
||||
registry = TestLibrary.createRegistryOnEphemeralPort();
|
||||
int port = TestLibrary.getRegistryPort(registry);
|
||||
/*
|
||||
* create object with custom ref and bind in registry
|
||||
*/
|
||||
System.err.println("creating UseCustomRef...");
|
||||
UseCustomRef cr = new UseCustomRef();
|
||||
RemoteRef ref = cr.getRef();
|
||||
if (!(ref instanceof CustomServerRef)) {
|
||||
TestLibrary.bomb("test failed: reference not " +
|
||||
"instanceof CustomServerRef");
|
||||
}
|
||||
|
||||
String name = "//:" + port + "/UseCustomRef";
|
||||
// String name = "UseCustomRef";
|
||||
System.err.println("binding object in registry...");
|
||||
Naming.rebind(name, cr);
|
||||
|
||||
/*
|
||||
* look up object and invoke its ping method
|
||||
*/
|
||||
System.err.println("ping object...");
|
||||
obj = (Ping) Naming.lookup(name);
|
||||
obj.ping();
|
||||
|
||||
/*
|
||||
* pass object with custom ref in remote call
|
||||
*/
|
||||
System.err.println("pass object in remote call...");
|
||||
obj.receiveAndPing(cr);
|
||||
|
||||
/*
|
||||
* write remote object with custom ref to output stream
|
||||
*/
|
||||
System.err.println("writing remote object to stream...");
|
||||
ByteArrayOutputStream bout = new ByteArrayOutputStream();
|
||||
ObjectOutputStream out = new ObjectOutputStream(bout);
|
||||
out.writeObject(cr);
|
||||
out.flush();
|
||||
out.close();
|
||||
|
||||
/*
|
||||
* read back remote object from output stream
|
||||
*/
|
||||
System.err.println("reading remote object from stream...");
|
||||
ObjectInputStream in = new ObjectInputStream(
|
||||
new ByteArrayInputStream(bout.toByteArray()));
|
||||
cr = (UseCustomRef) in.readObject();
|
||||
|
||||
/*
|
||||
* re-export object and ping
|
||||
*/
|
||||
System.err.println("re-export object read...");
|
||||
cr.exportObject();
|
||||
System.err.println("look up object again...");
|
||||
Naming.rebind(name, cr);
|
||||
System.err.println("ping object read...");
|
||||
obj = (Ping) Naming.lookup(name);
|
||||
obj.ping();
|
||||
System.err.println("TEST PASSED");
|
||||
Naming.unbind(name);
|
||||
cr = null;
|
||||
|
||||
} catch (Exception e) {
|
||||
TestLibrary.bomb("test failed with exception: ", e);
|
||||
} finally {
|
||||
TestLibrary.unexport(obj);
|
||||
TestLibrary.unexport(registry);
|
||||
|
||||
registry = null;
|
||||
obj = null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class CustomServerRef
|
||||
extends sun.rmi.server.UnicastServerRef
|
||||
{
|
||||
public CustomServerRef() {}
|
||||
|
||||
public CustomServerRef(LiveRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
/*****
|
||||
public CustomServerRef(int port,
|
||||
RMIClientSocketFactory csf,
|
||||
RMIServerSocketFactory ssf)
|
||||
{
|
||||
super (new LiveRef(port, csf, ssf));
|
||||
}
|
||||
*****/
|
||||
|
||||
public String getRefClass(ObjectOutput out) {
|
||||
return "";
|
||||
}
|
||||
|
||||
protected void unmarshalCustomCallData(ObjectInput in)
|
||||
throws IOException, ClassNotFoundException
|
||||
{
|
||||
System.err.println("unmarshalling call data...");
|
||||
String s = (String) (in.readObject());
|
||||
System.err.println(s);
|
||||
}
|
||||
|
||||
protected RemoteRef getClientRef() {
|
||||
return new CustomRef(ref);
|
||||
}
|
||||
}
|
||||
|
||||
public static class CustomRef extends sun.rmi.server.UnicastRef {
|
||||
|
||||
public CustomRef() {
|
||||
}
|
||||
|
||||
public CustomRef(sun.rmi.transport.LiveRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
protected void marshalCustomCallData(ObjectOutput out)
|
||||
throws IOException
|
||||
{
|
||||
// this custom data ensures that a custom server
|
||||
// ref has written the relevant information.
|
||||
System.err.println("marshalling call data...");
|
||||
out.writeObject("hello there.");
|
||||
}
|
||||
|
||||
public String getRefClass(ObjectOutput out) {
|
||||
return "";
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue