--- old/test/nashorn/src/jdk/dynalink/test/DynamicLinkerFactoryTest.java 2020-04-15 19:24:33.000000000 +0530 +++ /dev/null 2020-04-15 19:24:34.000000000 +0530 @@ -1,326 +0,0 @@ -/* - * Copyright (c) 2015, 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. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * 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. - */ -package jdk.dynalink.test; - -import static jdk.dynalink.StandardNamespace.PROPERTY; -import static jdk.dynalink.StandardOperation.GET; - -import java.lang.invoke.CallSite; -import java.lang.invoke.MethodHandle; -import java.lang.invoke.MethodHandles; -import java.lang.invoke.MethodType; -import java.util.List; -import java.util.ServiceConfigurationError; -import javax.script.ScriptEngine; -import javax.script.ScriptEngineManager; -import jdk.dynalink.CallSiteDescriptor; -import jdk.dynalink.DynamicLinker; -import jdk.dynalink.DynamicLinkerFactory; -import jdk.dynalink.NoSuchDynamicMethodException; -import jdk.dynalink.Operation; -import jdk.dynalink.StandardNamespace; -import jdk.dynalink.StandardOperation; -import jdk.dynalink.beans.StaticClass; -import jdk.dynalink.linker.GuardedInvocation; -import jdk.dynalink.linker.GuardingDynamicLinker; -import jdk.dynalink.linker.LinkRequest; -import jdk.dynalink.linker.LinkerServices; -import jdk.dynalink.support.SimpleRelinkableCallSite; -import jdk.nashorn.api.scripting.AbstractJSObject; -import org.testng.Assert; -import org.testng.annotations.Test; - -@SuppressWarnings("javadoc") -public class DynamicLinkerFactoryTest { - - private static final Operation GET_PROPERTY = GET.withNamespace(PROPERTY); - - private static DynamicLinkerFactory newDynamicLinkerFactory(final boolean resetClassLoader) { - final DynamicLinkerFactory factory = new DynamicLinkerFactory(); - if (resetClassLoader) { - factory.setClassLoader(null); - } - return factory; - } - - @Test - public void callSiteCreationTest() { - final DynamicLinkerFactory factory = newDynamicLinkerFactory(true); - final DynamicLinker linker = factory.createLinker(); - final StandardOperation[] operations = StandardOperation.values(); - final MethodType mt = MethodType.methodType(Object.class, Object.class); - for (final Operation op : operations) { - final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor( - MethodHandles.publicLookup(), op, mt))); - Assert.assertNotNull(cs); - Assert.assertEquals(cs.type(), mt); - Assert.assertNotNull(cs.getTarget()); - } - } - - @Test - public void fallbackLinkerTest() { - final DynamicLinkerFactory factory = newDynamicLinkerFactory(true); - final Operation myOperation = new Operation() { - }; - final boolean[] reachedFallback = { false }; - factory.setFallbackLinkers((GuardingDynamicLinker) (final LinkRequest linkRequest, final LinkerServices linkerServices) -> { - Assert.assertEquals(linkRequest.getCallSiteDescriptor().getOperation(), myOperation); - reachedFallback[0] = true; - return null; - }); - - final DynamicLinker linker = factory.createLinker(); - final MethodType mt = MethodType.methodType(Object.class); - final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor( - MethodHandles.publicLookup(), myOperation, mt))); - - // linking the call site initially does not invoke the linkers! - Assert.assertFalse(reachedFallback[0]); - try { - cs.getTarget().invoke(); - } catch (final NoSuchDynamicMethodException nsdm) { - // we do expect NoSuchDynamicMethod! - // because our dummy fallback linker returns null! - } catch (final Throwable th) { - throw new RuntimeException("should not reach here with: " + th); - } - - // check that the control reached fallback linker! - Assert.assertTrue(reachedFallback[0]); - } - - @Test - public void priorityLinkerTest() { - final DynamicLinkerFactory factory = newDynamicLinkerFactory(true); - final Operation myOperation = new Operation() { - }; - final boolean[] reachedProrityLinker = { false }; - factory.setPrioritizedLinker((GuardingDynamicLinker) (final LinkRequest linkRequest, final LinkerServices linkerServices) -> { - Assert.assertEquals(linkRequest.getCallSiteDescriptor().getOperation(), myOperation); - reachedProrityLinker[0] = true; - return null; - }); - - final DynamicLinker linker = factory.createLinker(); - final MethodType mt = MethodType.methodType(Object.class); - final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor( - MethodHandles.publicLookup(), myOperation, mt))); - - // linking the call site initially does not invoke the linkers! - Assert.assertFalse(reachedProrityLinker[0]); - try { - cs.getTarget().invoke(); - } catch (final NoSuchDynamicMethodException nsdm) { - // we do expect NoSuchDynamicMethod! - // because our dummy priority linker returns null! - } catch (final Throwable th) { - throw new RuntimeException("should not reach here with: " + th); - } - - // check that the control reached fallback linker! - Assert.assertTrue(reachedProrityLinker[0]); - } - - @Test - public void priorityAndFallbackLinkerTest() { - final DynamicLinkerFactory factory = newDynamicLinkerFactory(true); - final Operation myOperation = new Operation() { - }; - final int[] linkerReachCounter = { 0 }; - factory.setPrioritizedLinker((GuardingDynamicLinker) (final LinkRequest linkRequest, final LinkerServices linkerServices) -> { - Assert.assertEquals(linkRequest.getCallSiteDescriptor().getOperation(), myOperation); - linkerReachCounter[0]++; - return null; - }); - factory.setFallbackLinkers((GuardingDynamicLinker) (final LinkRequest linkRequest, final LinkerServices linkerServices) -> { - Assert.assertEquals(linkRequest.getCallSiteDescriptor().getOperation(), myOperation); - Assert.assertEquals(linkerReachCounter[0], 1); - linkerReachCounter[0]++; - return null; - }); - - final DynamicLinker linker = factory.createLinker(); - final MethodType mt = MethodType.methodType(Object.class); - final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor( - MethodHandles.publicLookup(), myOperation, mt))); - - // linking the call site initially does not invoke the linkers! - Assert.assertEquals(linkerReachCounter[0], 0); - - try { - cs.getTarget().invoke(); - } catch (final NoSuchDynamicMethodException nsdm) { - // we do expect NoSuchDynamicMethod! - } catch (final Throwable th) { - throw new RuntimeException("should not reach here with: " + th); - } - - Assert.assertEquals(linkerReachCounter[0], 2); - } - - @Test - public void prelinkTransformerTest() throws Throwable { - final DynamicLinkerFactory factory = newDynamicLinkerFactory(true); - final boolean[] reachedPrelinkTransformer = { false }; - - factory.setPrelinkTransformer((final GuardedInvocation inv, final LinkRequest linkRequest, final LinkerServices linkerServices) -> { - reachedPrelinkTransformer[0] = true; - // just identity transformer! - return inv; - }); - - final MethodType mt = MethodType.methodType(Object.class, Object.class, String.class); - final DynamicLinker linker = factory.createLinker(); - final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor( - MethodHandles.publicLookup(), GET_PROPERTY, mt))); - Assert.assertFalse(reachedPrelinkTransformer[0]); - Assert.assertEquals(cs.getTarget().invoke(new Object(), "class"), Object.class); - Assert.assertTrue(reachedPrelinkTransformer[0]); - } - - @Test - public void internalObjectsFilterTest() throws Throwable { - final DynamicLinkerFactory factory = newDynamicLinkerFactory(true); - final boolean[] reachedInternalObjectsFilter = { false }; - - factory.setInternalObjectsFilter((final MethodHandle mh) -> { - reachedInternalObjectsFilter[0] = true; - return mh; - }); - - final MethodType mt = MethodType.methodType(Object.class, Object.class, String.class); - final DynamicLinker linker = factory.createLinker(); - final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor( - MethodHandles.publicLookup(), GET_PROPERTY, mt))); - Assert.assertFalse(reachedInternalObjectsFilter[0]); - Assert.assertEquals(cs.getTarget().invoke(new Object(), "class"), Object.class); - Assert.assertTrue(reachedInternalObjectsFilter[0]); - } - - private static void checkOneAutoLoadingError(final DynamicLinkerFactory factory) { - // expect one error as we have one untrusted linker exporter in META-INF/services - final List autoLoadingErrors = factory.getAutoLoadingErrors(); - // single error ... - Assert.assertFalse(autoLoadingErrors.isEmpty()); - final Throwable cause = autoLoadingErrors.get(0).getCause(); - // .. due to permission check.. - Assert.assertTrue(cause.toString().contains("dynalink.exportLinkersAutomatically")); - } - - @Test - public void autoLoadedLinkerNegativeTest() { - // enable auto loaded linkers - final DynamicLinkerFactory factory = newDynamicLinkerFactory(false); - factory.createLinker(); - checkOneAutoLoadingError(factory); - } - - @Test - public void autoLoadedLinkerTest() { - testAutoLoadedLinkerInvoked(new Object(), "toString"); - } - - @Test - public void autoLoadedLinkerSeesStaticMethod() { - testAutoLoadedLinkerInvoked(StaticClass.forClass(System.class), "currentTimeMillis"); - } - - private static void testAutoLoadedLinkerInvoked(final Object target, final String methodName) { - final DynamicLinkerFactory factory = newDynamicLinkerFactory(false); - final DynamicLinker linker = factory.createLinker(); - - // we should still get one error due to untrusted dynamic linker exporter! - checkOneAutoLoadingError(factory); - - final MethodType mt = MethodType.methodType(Object.class, Object.class); - final CallSiteDescriptor testDescriptor = new CallSiteDescriptor(MethodHandles.publicLookup(), - GET.withNamespace(StandardNamespace.METHOD).named(methodName), mt); - final CallSite cs = linker.link(new SimpleRelinkableCallSite(testDescriptor)); - - TrustedGuardingDynamicLinkerExporter.enable(); - try { - cs.getTarget().invoke(target); - // The linker was loaded and it observed our invocation - Assert.assertTrue(TrustedGuardingDynamicLinkerExporter.isLastCallSiteDescriptor(testDescriptor)); - } catch (final Throwable th) { - throw new RuntimeException(th); - } finally { - TrustedGuardingDynamicLinkerExporter.disable(); - } - - } - - @Test - public void nashornExportedLinkerJSObjectTest() { - final DynamicLinkerFactory factory = newDynamicLinkerFactory(false); - final DynamicLinker linker = factory.createLinker(); - - final MethodType mt = MethodType.methodType(Object.class, Object.class); - final Operation op = GET_PROPERTY.named("foo"); - final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor( - MethodHandles.publicLookup(), op, mt))); - final boolean[] reachedGetMember = new boolean[1]; - // check that the nashorn exported linker can be used for user defined JSObject - final Object obj = new AbstractJSObject() { - @Override - public Object getMember(final String name) { - reachedGetMember[0] = true; - return name.equals("foo")? "bar" : ""; - } - }; - - Object value = null; - try { - value = cs.getTarget().invoke(obj); - } catch (final Throwable th) { - throw new RuntimeException(th); - } - - Assert.assertTrue(reachedGetMember[0]); - Assert.assertEquals(value, "bar"); - } - - @Test - public void nashornExportedLinkerScriptObjectMirrorTest() { - final DynamicLinkerFactory factory = newDynamicLinkerFactory(false); - final DynamicLinker linker = factory.createLinker(); - - // check that the nashorn exported linker can be used for ScriptObjectMirror - final ScriptEngine engine = new ScriptEngineManager().getEngineByName("nashorn"); - final MethodType mt = MethodType.methodType(Object.class, Object.class); - final Operation op = GET_PROPERTY.named("foo"); - final CallSite cs = linker.link(new SimpleRelinkableCallSite(new CallSiteDescriptor( - MethodHandles.publicLookup(), op, mt))); - Object value = null; - try { - final Object obj = engine.eval("({ foo: 'hello' })"); - value = cs.getTarget().invoke(obj); - } catch (final Throwable th) { - throw new RuntimeException(th); - } - Assert.assertEquals(value, "hello"); - } -}