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
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Copyright (c) 2021, 2023, 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.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import impl.SimpleResolverProviderImpl;
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Test that InetAddress caching security properties work as expected
|
||||
* when a custom resolver is installed.
|
||||
* @library lib providers/simple
|
||||
* @build test.library/testlib.ResolutionRegistry
|
||||
* simple.provider/impl.SimpleResolverProviderImpl AddressesCachingTest
|
||||
* @run testng/othervm -Djava.security.properties=${test.src}/props/NeverCache.props
|
||||
* -Dtest.cachingDisabled=true AddressesCachingTest
|
||||
* @run testng/othervm -Djava.security.properties=${test.src}/props/ForeverCache.props
|
||||
* -Dtest.cachingDisabled=false AddressesCachingTest
|
||||
* @run testng/othervm
|
||||
* -Djava.security.properties=${test.src}/props/NeverCacheIgnoreMinusStale.props
|
||||
* -Dtest.cachingDisabled=true AddressesCachingTest
|
||||
* @run testng/othervm
|
||||
* -Djava.security.properties=${test.src}/props/NeverCacheIgnorePositiveStale.props
|
||||
* -Dtest.cachingDisabled=true AddressesCachingTest
|
||||
* @run testng/othervm
|
||||
* -Djava.security.properties=${test.src}/props/NeverCacheIgnoreZeroStale.props
|
||||
* -Dtest.cachingDisabled=true AddressesCachingTest
|
||||
* @run testng/othervm
|
||||
* -Djava.security.properties=${test.src}/props/ForeverCacheIgnoreMinusStale.props
|
||||
* -Dtest.cachingDisabled=false AddressesCachingTest
|
||||
* @run testng/othervm
|
||||
* -Djava.security.properties=${test.src}/props/ForeverCacheIgnorePositiveStale.props
|
||||
* -Dtest.cachingDisabled=false AddressesCachingTest
|
||||
* @run testng/othervm
|
||||
* -Djava.security.properties=${test.src}/props/ForeverCacheIgnoreZeroStale.props
|
||||
* -Dtest.cachingDisabled=false AddressesCachingTest
|
||||
*/
|
||||
public class AddressesCachingTest {
|
||||
|
||||
@Test
|
||||
public void testPositiveCaching() {
|
||||
boolean observedTwoLookups = performLookups(false);
|
||||
if (CACHING_DISABLED) {
|
||||
Assert.assertTrue(observedTwoLookups,
|
||||
"Two positive lookups are expected with caching disabled");
|
||||
} else {
|
||||
Assert.assertFalse(observedTwoLookups,
|
||||
"Only one positive lookup is expected with caching enabled");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNegativeCaching() {
|
||||
boolean observedTwoLookups = performLookups(true);
|
||||
if (CACHING_DISABLED) {
|
||||
Assert.assertTrue(observedTwoLookups,
|
||||
"Two negative lookups are expected with caching disabled");
|
||||
} else {
|
||||
Assert.assertFalse(observedTwoLookups,
|
||||
"Only one negative lookup is expected with caching enabled");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Performs two subsequent positive or negative lookups.
|
||||
* Returns true if the timestamp of this lookups differs,
|
||||
* false otherwise.
|
||||
*/
|
||||
private static boolean performLookups(boolean performNegativeLookup) {
|
||||
doLookup(performNegativeLookup);
|
||||
long firstTimestamp = SimpleResolverProviderImpl.getLastLookupTimestamp();
|
||||
doLookup(performNegativeLookup);
|
||||
long secondTimestamp = SimpleResolverProviderImpl.getLastLookupTimestamp();
|
||||
return firstTimestamp != secondTimestamp;
|
||||
}
|
||||
|
||||
// Performs negative or positive lookup.
|
||||
// It is a test error if UnknownHostException is thrown during positive lookup.
|
||||
// It is a test error if UnknownHostException is NOT thrown during negative lookup.
|
||||
private static void doLookup(boolean performNegativeLookup) {
|
||||
String hostName = performNegativeLookup ? "notKnowHost.org" : "javaTest.org";
|
||||
try {
|
||||
InetAddress.getByName(hostName);
|
||||
if (performNegativeLookup) {
|
||||
Assert.fail("Host name is expected to get unresolved");
|
||||
}
|
||||
} catch (UnknownHostException uhe) {
|
||||
if (!performNegativeLookup) {
|
||||
Assert.fail("Host name is expected to get resolved");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper system property that signals to the test if both negative and positive
|
||||
// caches are disabled.
|
||||
private static final boolean CACHING_DISABLED = Boolean.getBoolean("test.cachingDisabled");
|
||||
}
|
||||
|
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Copyright (c) 2023, 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.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import impl.SimpleResolverProviderImpl;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Test that stale InetAddress caching security properties work as
|
||||
* expected when a custom resolver is installed.
|
||||
* @library lib providers/simple
|
||||
* @build test.library/testlib.ResolutionRegistry
|
||||
* simple.provider/impl.SimpleResolverProviderImpl AddressesStaleCachingTest
|
||||
* @run testng/othervm -Djava.security.properties=${test.src}/props/CacheStale.props AddressesStaleCachingTest
|
||||
*/
|
||||
public class AddressesStaleCachingTest {
|
||||
|
||||
private static class Lookup {
|
||||
private final byte[] address;
|
||||
private final long timestamp;
|
||||
|
||||
private Lookup(byte[] address, long timestamp) {
|
||||
this.address = address;
|
||||
this.timestamp = timestamp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates successful and unsuccessful lookups when the stale cache is
|
||||
* enabled.
|
||||
*/
|
||||
@Test
|
||||
public void testRefresh() throws Exception{
|
||||
// The first request is to save the data into the cache
|
||||
Lookup first = doLookup(false, 0);
|
||||
|
||||
Thread.sleep(10000); // intentionally big delay > x2 stale property
|
||||
// The refreshTime is expired, we will do the successful lookup.
|
||||
Lookup second = doLookup(false, 0);
|
||||
Assert.assertNotEquals(first.timestamp, second.timestamp,
|
||||
"Two lookups are expected");
|
||||
|
||||
Thread.sleep(10000); // intentionally big delay > x2 stale property
|
||||
// The refreshTime is expired again, we will do the failed lookup.
|
||||
Lookup third = doLookup(true, 0);
|
||||
Assert.assertNotEquals(second.timestamp, third.timestamp,
|
||||
"Two lookups are expected");
|
||||
|
||||
// The stale cache is enabled, so we should get valid/same data for
|
||||
// all requests(even for the failed request).
|
||||
Assert.assertEquals(first.address, second.address,
|
||||
"Same address is expected");
|
||||
Assert.assertEquals(second.address, third.address,
|
||||
"Same address is expected");
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates that only one thread is blocked during "refresh", all others
|
||||
* will continue to use the "stale" data.
|
||||
*/
|
||||
@Test
|
||||
public void testOnlyOneThreadIsBlockedDuringRefresh() throws Exception {
|
||||
long timeout = System.nanoTime() + TimeUnit.SECONDS.toNanos(12);
|
||||
doLookup(false, timeout);
|
||||
Thread.sleep(9000);
|
||||
|
||||
CountDownLatch blockServer = new CountDownLatch(1);
|
||||
SimpleResolverProviderImpl.setBlocker(blockServer);
|
||||
|
||||
Thread ts[] = new Thread[10];
|
||||
CountDownLatch wait9 = new CountDownLatch(ts.length - 1);
|
||||
CountDownLatch wait10 = new CountDownLatch(ts.length);
|
||||
CountDownLatch start = new CountDownLatch(ts.length);
|
||||
for (int i = 0; i < ts.length; i++) {
|
||||
ts[i] = new Thread(() -> {
|
||||
start.countDown();
|
||||
try {
|
||||
start.await();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
doLookup(true, timeout);
|
||||
wait9.countDown();
|
||||
wait10.countDown();
|
||||
});
|
||||
}
|
||||
for (Thread t : ts) {
|
||||
t.start();
|
||||
}
|
||||
if (!wait9.await(10, TimeUnit.SECONDS)) {
|
||||
blockServer.countDown();
|
||||
throw new RuntimeException("Some threads hang");
|
||||
}
|
||||
blockServer.countDown();
|
||||
if (!wait10.await(10, TimeUnit.SECONDS)) {
|
||||
throw new RuntimeException("The last thread hangs");
|
||||
}
|
||||
}
|
||||
|
||||
private static Lookup doLookup(boolean error, long timeout) {
|
||||
SimpleResolverProviderImpl.setUnreachableServer(error);
|
||||
try {
|
||||
byte[] firstAddress = InetAddress.getByName("javaTest.org").getAddress();
|
||||
long firstTimestamp = SimpleResolverProviderImpl.getLastLookupTimestamp();
|
||||
|
||||
byte[] secondAddress = InetAddress.getByName("javaTest.org").getAddress();
|
||||
long secondTimestamp = SimpleResolverProviderImpl.getLastLookupTimestamp();
|
||||
|
||||
Assert.assertEquals(firstAddress, secondAddress,
|
||||
"Same address is expected");
|
||||
if (timeout == 0 || timeout - System.nanoTime() > 0) {
|
||||
Assert.assertEquals(firstTimestamp, secondTimestamp,
|
||||
"Only one positive lookup is expected with caching enabled");
|
||||
}
|
||||
return new Lookup(firstAddress, firstTimestamp);
|
||||
} catch (UnknownHostException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static impl.WithBootstrapResolverUsageProvider.numberOfGetCalls;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Test that InetAddress class properly avoids stack-overflow by
|
||||
* correctly tracking the bootstrap resolver instance when
|
||||
* InetAddressResolverProvider.get method uses InetAddress lookup API.
|
||||
* @library providers/bootstrapUsage
|
||||
* @build bootstrap.usage.provider/impl.WithBootstrapResolverUsageProvider
|
||||
* @run testng/othervm BootstrapResolverUsageTest
|
||||
*/
|
||||
|
||||
public class BootstrapResolverUsageTest {
|
||||
|
||||
@Test
|
||||
public void testSuccessfulProviderInstantiationTest() throws Exception {
|
||||
System.err.println(InetAddress.getAllByName(InetAddress.getLocalHost().getHostName()));
|
||||
Assert.assertEquals(numberOfGetCalls, 1,
|
||||
"InetAddressResolverProvider.get was called more than once");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.annotations.BeforeTest;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.net.spi.InetAddressResolver;
|
||||
|
||||
import static org.testng.Assert.*;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary white-box test to check that the built-in resolver
|
||||
* is used by default.
|
||||
* @modules java.base/java.net:open
|
||||
* @run testng/othervm BuiltInResolverTest
|
||||
*/
|
||||
|
||||
public class BuiltInResolverTest {
|
||||
|
||||
private Field builtInResolverField, resolverField;
|
||||
|
||||
@BeforeTest
|
||||
public void beforeTest() throws NoSuchFieldException {
|
||||
Class<InetAddress> inetAddressClass = InetAddress.class;
|
||||
// Needs to happen for InetAddress.resolver to be initialized
|
||||
try {
|
||||
InetAddress.getByName("test");
|
||||
} catch (UnknownHostException e) {
|
||||
// Do nothing, only want to assign resolver
|
||||
}
|
||||
builtInResolverField = inetAddressClass.getDeclaredField("BUILTIN_RESOLVER");
|
||||
builtInResolverField.setAccessible(true);
|
||||
resolverField = inetAddressClass.getDeclaredField("resolver");
|
||||
resolverField.setAccessible(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultNSContext() throws IllegalAccessException {
|
||||
// Test that the resolver used by default is the BUILTIN_RESOLVER
|
||||
Object defaultResolverObject = builtInResolverField.get(InetAddressResolver.class);
|
||||
Object usedResolverObject = resolverField.get(InetAddressResolver.class);
|
||||
|
||||
assertTrue(defaultResolverObject == usedResolverObject);
|
||||
|
||||
String defaultClassName = defaultResolverObject.getClass().getCanonicalName();
|
||||
String currentClassName = usedResolverObject.getClass().getCanonicalName();
|
||||
|
||||
assertNotNull(defaultClassName, "defaultClassName not set");
|
||||
assertNotNull(currentClassName, "currentClassName name not set");
|
||||
|
||||
assertEquals(currentClassName, defaultClassName,
|
||||
"BUILTIN_RESOLVER resolver was not used.");
|
||||
System.err.println("Resolver used by default is the built-in resolver");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Arrays;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary checks that InetAddress forward lookup API throw UnknownHostException
|
||||
* when resolver returns empty address stream.
|
||||
* @library providers/empty
|
||||
* @build empty.results.provider/impl.EmptyResultsProviderImpl
|
||||
* @run testng/othervm EmptyResultsStreamTest
|
||||
*/
|
||||
public class EmptyResultsStreamTest {
|
||||
|
||||
@Test(expectedExceptions = UnknownHostException.class)
|
||||
public void getAllByNameTest() throws UnknownHostException {
|
||||
System.err.println("getAllByName unexpectedly completed: " +
|
||||
Arrays.deepToString(InetAddress.getAllByName("test1.org")));
|
||||
}
|
||||
|
||||
@Test(expectedExceptions = UnknownHostException.class)
|
||||
public void getByNameTest() throws UnknownHostException {
|
||||
System.err.println("getByName unexpectedly completed: " +
|
||||
InetAddress.getByName("test2.org"));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
/**
|
||||
* @test
|
||||
* @summary Test that provider which uses InetAddress APIs during its initialization
|
||||
* wouldn't cause stack overflow and will be successfully installed.
|
||||
* @library providers/recursive
|
||||
* @build recursive.init.provider/impl.InetAddressUsageInGetProviderImpl
|
||||
* @run testng/othervm InetAddressUsageInGetProviderTest
|
||||
*/
|
||||
|
||||
public class InetAddressUsageInGetProviderTest {
|
||||
|
||||
@Test
|
||||
public void testSuccessfulProviderInstantiationTest() throws Exception {
|
||||
System.err.println(InetAddress.getAllByName(InetAddress.getLocalHost().getHostName()));
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,172 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static java.net.spi.InetAddressResolver.LookupPolicy.IPV4;
|
||||
import static java.net.spi.InetAddressResolver.LookupPolicy.IPV4_FIRST;
|
||||
import static java.net.spi.InetAddressResolver.LookupPolicy.IPV6;
|
||||
import static java.net.spi.InetAddressResolver.LookupPolicy.IPV6_FIRST;
|
||||
|
||||
import jdk.test.lib.net.IPSupport;
|
||||
import jdk.test.lib.NetworkConfiguration;
|
||||
import org.testng.annotations.Test;
|
||||
import org.testng.Assert;
|
||||
import org.testng.SkipException;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Test that platform lookup characteristic value is correctly initialized from
|
||||
* system properties affecting order and type of queried addresses.
|
||||
* @library lib providers/simple /test/lib
|
||||
* @build test.library/testlib.ResolutionRegistry simple.provider/impl.SimpleResolverProviderImpl
|
||||
* jdk.test.lib.net.IPSupport LookupPolicyMappingTest
|
||||
* @run testng/othervm LookupPolicyMappingTest
|
||||
* @run testng/othervm -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses=true LookupPolicyMappingTest
|
||||
* @run testng/othervm -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses=false LookupPolicyMappingTest
|
||||
* @run testng/othervm -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses=system LookupPolicyMappingTest
|
||||
* @run testng/othervm -Djava.net.preferIPv4Stack=true -Djava.net.preferIPv6Addresses LookupPolicyMappingTest
|
||||
* @run testng/othervm -Djava.net.preferIPv4Stack=true LookupPolicyMappingTest
|
||||
* @run testng/othervm -Djava.net.preferIPv4Stack=false -Djava.net.preferIPv6Addresses=true LookupPolicyMappingTest
|
||||
* @run testng/othervm -Djava.net.preferIPv4Stack=false -Djava.net.preferIPv6Addresses=false LookupPolicyMappingTest
|
||||
* @run testng/othervm -Djava.net.preferIPv4Stack=false -Djava.net.preferIPv6Addresses=system LookupPolicyMappingTest
|
||||
* @run testng/othervm -Djava.net.preferIPv4Stack=false -Djava.net.preferIPv6Addresses LookupPolicyMappingTest
|
||||
* @run testng/othervm -Djava.net.preferIPv4Stack=false LookupPolicyMappingTest
|
||||
* @run testng/othervm -Djava.net.preferIPv4Stack -Djava.net.preferIPv6Addresses=true LookupPolicyMappingTest
|
||||
* @run testng/othervm -Djava.net.preferIPv4Stack -Djava.net.preferIPv6Addresses=false LookupPolicyMappingTest
|
||||
* @run testng/othervm -Djava.net.preferIPv4Stack -Djava.net.preferIPv6Addresses=system LookupPolicyMappingTest
|
||||
* @run testng/othervm -Djava.net.preferIPv4Stack -Djava.net.preferIPv6Addresses LookupPolicyMappingTest
|
||||
* @run testng/othervm -Djava.net.preferIPv4Stack LookupPolicyMappingTest
|
||||
* @run testng/othervm -Djava.net.preferIPv6Addresses=true LookupPolicyMappingTest
|
||||
* @run testng/othervm -Djava.net.preferIPv6Addresses=false LookupPolicyMappingTest
|
||||
* @run testng/othervm -Djava.net.preferIPv6Addresses=system LookupPolicyMappingTest
|
||||
* @run testng/othervm -Djava.net.preferIPv6Addresses LookupPolicyMappingTest
|
||||
*/
|
||||
|
||||
public class LookupPolicyMappingTest {
|
||||
|
||||
@Test
|
||||
public void testSystemProperties() throws Exception {
|
||||
|
||||
// Check if platform network configuration matches the test requirements,
|
||||
// if not throw a SkipException
|
||||
checkPlatformNetworkConfiguration();
|
||||
|
||||
System.err.println("javaTest.org resolved to:" + Arrays.deepToString(
|
||||
InetAddress.getAllByName("javaTest.org")));
|
||||
|
||||
// Acquire runtime characteristics from the test NSP
|
||||
int runtimeCharacteristics = impl.SimpleResolverProviderImpl.lastLookupPolicy().characteristics();
|
||||
|
||||
// Calculate expected lookup policy characteristic
|
||||
String preferIPv4Stack = System.getProperty("java.net.preferIPv4Stack");
|
||||
String preferIPv6Addresses = System.getProperty("java.net.preferIPv6Addresses");
|
||||
String expectedResultsKey = calculateMapKey(preferIPv4Stack, preferIPv6Addresses);
|
||||
int expectedCharacteristics = EXPECTED_RESULTS_MAP.get(expectedResultsKey);
|
||||
|
||||
Assert.assertTrue(characteristicsMatch(
|
||||
runtimeCharacteristics, expectedCharacteristics), "Unexpected LookupPolicy observed");
|
||||
}
|
||||
|
||||
// Throws SkipException if platform doesn't support required IP address types
|
||||
static void checkPlatformNetworkConfiguration() {
|
||||
IPSupport.throwSkippedExceptionIfNonOperational();
|
||||
IPSupport.printPlatformSupport(System.err);
|
||||
NetworkConfiguration.printSystemConfiguration(System.err);
|
||||
// If preferIPv4=true and no IPv4 - skip
|
||||
if (IPSupport.preferIPv4Stack()) {
|
||||
if (!IPSupport.hasIPv4()) {
|
||||
throw new SkipException("Skip tests - IPv4 support required");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
record ExpectedResult(String ipv4stack, String ipv6addresses, int characteristics) {
|
||||
ExpectedResult {
|
||||
if (!IPSupport.hasIPv4()) {
|
||||
characteristics = IPV6;
|
||||
} else if (!IPSupport.hasIPv6()) {
|
||||
characteristics = IPV4;
|
||||
}
|
||||
}
|
||||
|
||||
public String key() {
|
||||
return calculateMapKey(ipv4stack, ipv6addresses);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Each row describes a combination of 'preferIPv4Stack', 'preferIPv6Addresses'
|
||||
* values and the expected characteristic value
|
||||
*/
|
||||
private static List<ExpectedResult> EXPECTED_RESULTS_TABLE = List.of(
|
||||
new ExpectedResult("true", "true", IPV4),
|
||||
new ExpectedResult("true", "false", IPV4),
|
||||
new ExpectedResult("true", "system", IPV4),
|
||||
new ExpectedResult("true", "", IPV4),
|
||||
new ExpectedResult("true", null, IPV4),
|
||||
|
||||
new ExpectedResult("false", "true", IPV4 | IPV6 | IPV6_FIRST),
|
||||
new ExpectedResult("false", "false", IPV4 | IPV6 | IPV4_FIRST),
|
||||
new ExpectedResult("false", "system", IPV4 | IPV6),
|
||||
new ExpectedResult("false", "", IPV4 | IPV6 | IPV4_FIRST),
|
||||
new ExpectedResult("false", null, IPV4 | IPV6 | IPV4_FIRST),
|
||||
|
||||
new ExpectedResult("", "true", IPV4 | IPV6 | IPV6_FIRST),
|
||||
new ExpectedResult("", "false", IPV4 | IPV6 | IPV4_FIRST),
|
||||
new ExpectedResult("", "system", IPV4 | IPV6),
|
||||
new ExpectedResult("", "", IPV4 | IPV6 | IPV4_FIRST),
|
||||
new ExpectedResult("", null, IPV4 | IPV6 | IPV4_FIRST),
|
||||
|
||||
new ExpectedResult(null, "true", IPV4 | IPV6 | IPV6_FIRST),
|
||||
new ExpectedResult(null, "false", IPV4 | IPV6 | IPV4_FIRST),
|
||||
new ExpectedResult(null, "system", IPV4 | IPV6),
|
||||
new ExpectedResult(null, "", IPV4 | IPV6 | IPV4_FIRST),
|
||||
new ExpectedResult(null, null, IPV4 | IPV6 | IPV4_FIRST));
|
||||
|
||||
private static final Map<String, Integer> EXPECTED_RESULTS_MAP = calculateExpectedCharacteristics();
|
||||
|
||||
private static Map<String, Integer> calculateExpectedCharacteristics() {
|
||||
return EXPECTED_RESULTS_TABLE.stream()
|
||||
.collect(Collectors.toUnmodifiableMap(
|
||||
ExpectedResult::key,
|
||||
ExpectedResult::characteristics)
|
||||
);
|
||||
}
|
||||
|
||||
private static String calculateMapKey(String ipv4stack, String ipv6addresses) {
|
||||
return ipv4stack + "_" + ipv6addresses;
|
||||
}
|
||||
|
||||
private static boolean characteristicsMatch(int actual, int expected) {
|
||||
System.err.printf("Comparing characteristics:%n\tActual: %s%n\tExpected: %s%n",
|
||||
Integer.toBinaryString(actual),
|
||||
Integer.toBinaryString(expected));
|
||||
return (actual & (IPV4 | IPV6 | IPV4_FIRST | IPV6_FIRST)) == expected;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* 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
|
||||
* @summary check if LookupPolicy.of correctly handles valid and illegal
|
||||
* combinations of characteristics bit mask flags.
|
||||
* @run testng LookupPolicyOfTest
|
||||
*/
|
||||
|
||||
import org.testng.annotations.DataProvider;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.net.spi.InetAddressResolver.LookupPolicy;
|
||||
import java.util.List;
|
||||
|
||||
import static java.net.spi.InetAddressResolver.LookupPolicy.IPV4;
|
||||
import static java.net.spi.InetAddressResolver.LookupPolicy.IPV4_FIRST;
|
||||
import static java.net.spi.InetAddressResolver.LookupPolicy.IPV6;
|
||||
import static java.net.spi.InetAddressResolver.LookupPolicy.IPV6_FIRST;
|
||||
|
||||
public class LookupPolicyOfTest {
|
||||
|
||||
@Test(dataProvider = "validCharacteristics")
|
||||
public void testValidCharacteristicCombinations(List<Integer> validCombination) {
|
||||
LookupPolicy.of(bitFlagsToCharacteristicsValue(validCombination));
|
||||
}
|
||||
|
||||
@Test(dataProvider = "invalidCharacteristics", expectedExceptions = IllegalArgumentException.class)
|
||||
public void testInvalidCharacteristicCombinations(List<Integer> invalidCombination) {
|
||||
LookupPolicy.of(bitFlagsToCharacteristicsValue(invalidCombination));
|
||||
}
|
||||
|
||||
@DataProvider(name = "validCharacteristics")
|
||||
public Object[][] validCharacteristicValue() {
|
||||
return new Object[][]{
|
||||
{List.of(IPV4)},
|
||||
{List.of(IPV4, IPV4_FIRST)},
|
||||
{List.of(IPV6)},
|
||||
{List.of(IPV6, IPV6_FIRST)},
|
||||
{List.of(IPV4, IPV6)},
|
||||
{List.of(IPV4, IPV6, IPV4_FIRST)},
|
||||
{List.of(IPV4, IPV6, IPV6_FIRST)},
|
||||
// Custom flag values alongside to address type flags
|
||||
// that could be used by custom providers
|
||||
{List.of(IPV4, IPV6, 0x10)},
|
||||
{List.of(IPV4, IPV6, 0x20)},
|
||||
};
|
||||
}
|
||||
|
||||
@DataProvider(name = "invalidCharacteristics")
|
||||
public Object[][] illegalCharacteristicValue() {
|
||||
return new Object[][]{
|
||||
{List.of()},
|
||||
{List.of(IPV4_FIRST)},
|
||||
{List.of(IPV6_FIRST)},
|
||||
{List.of(IPV4_FIRST, IPV6_FIRST)},
|
||||
{List.of(IPV4, IPV6_FIRST)},
|
||||
{List.of(IPV6, IPV4_FIRST)},
|
||||
{List.of(IPV4, IPV6, IPV4_FIRST, IPV6_FIRST)},
|
||||
};
|
||||
}
|
||||
|
||||
private static int bitFlagsToCharacteristicsValue(List<Integer> bitFlagsList) {
|
||||
return bitFlagsList.stream()
|
||||
.reduce(0, (flag1, flag2) -> flag1 | flag2);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static impl.FaultyResolverProviderGetImpl.EXCEPTION_MESSAGE;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Test that InetAddress fast-fails if custom provider fails to
|
||||
* instantiate a resolver.
|
||||
* @library providers/faulty
|
||||
* @build faulty.provider/impl.FaultyResolverProviderGetImpl
|
||||
* @run testng/othervm ProviderGetExceptionTest
|
||||
*/
|
||||
|
||||
public class ProviderGetExceptionTest {
|
||||
|
||||
@Test
|
||||
public void getByNameExceptionTest() {
|
||||
String hostName = "test.host";
|
||||
System.out.println("Looking up address for the following host name:" + hostName);
|
||||
callInetAddressAndCheckException(() -> InetAddress.getByName(hostName));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getByAddressExceptionTest() {
|
||||
byte[] address = new byte[]{1, 2, 3, 4};
|
||||
System.out.println("Looking up host name for the following address:" + Arrays.toString(address));
|
||||
callInetAddressAndCheckException(() -> InetAddress.getByAddress(address).getHostName());
|
||||
}
|
||||
|
||||
private void callInetAddressAndCheckException(Assert.ThrowingRunnable apiCall) {
|
||||
IllegalArgumentException iae = Assert.expectThrows(IllegalArgumentException.class, apiCall);
|
||||
System.out.println("Got exception of expected type:" + iae);
|
||||
Assert.assertNull(iae.getCause(), "cause is not null");
|
||||
Assert.assertEquals(iae.getMessage(), EXCEPTION_MESSAGE);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import impl.ThrowingLookupsProviderImpl;
|
||||
|
||||
import static impl.ThrowingLookupsProviderImpl.RUNTIME_EXCEPTION_MESSAGE;
|
||||
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Test that only UnknownHostException is thrown if resolver
|
||||
* implementation throws RuntimeException during forward or reverse lookup.
|
||||
* @library providers/throwing
|
||||
* @build throwing.lookups.provider/impl.ThrowingLookupsProviderImpl
|
||||
* @run testng/othervm ResolutionWithExceptionTest
|
||||
*/
|
||||
|
||||
public class ResolutionWithExceptionTest {
|
||||
|
||||
@Test
|
||||
public void getByNameUnknownHostException() {
|
||||
ThrowingLookupsProviderImpl.throwRuntimeException = false;
|
||||
runGetByNameTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getByNameRuntimeException() {
|
||||
ThrowingLookupsProviderImpl.throwRuntimeException = true;
|
||||
runGetByNameTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getByAddressUnknownHostException() throws UnknownHostException {
|
||||
ThrowingLookupsProviderImpl.throwRuntimeException = false;
|
||||
runGetByAddressTest();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getByAddressRuntimeException() throws UnknownHostException {
|
||||
ThrowingLookupsProviderImpl.throwRuntimeException = true;
|
||||
runGetByAddressTest();
|
||||
}
|
||||
|
||||
private void runGetByNameTest() {
|
||||
// InetAddress.getByName() is expected to throw UnknownHostException in all cases
|
||||
UnknownHostException uhe = Assert.expectThrows(UnknownHostException.class,
|
||||
() -> InetAddress.getByName("doesnt.matter.com"));
|
||||
// If provider is expected to throw RuntimeException - check that UnknownHostException
|
||||
// is set as its cause
|
||||
if (ThrowingLookupsProviderImpl.throwRuntimeException) {
|
||||
Throwable cause = uhe.getCause();
|
||||
if (cause instanceof RuntimeException re) {
|
||||
// Check RuntimeException message
|
||||
Assert.assertEquals(re.getMessage(), RUNTIME_EXCEPTION_MESSAGE,
|
||||
"incorrect exception message");
|
||||
} else {
|
||||
Assert.fail("UnknownHostException cause is not RuntimeException");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void runGetByAddressTest() throws UnknownHostException {
|
||||
// getCanonicalHostName is not expected to throw an exception:
|
||||
// if there is an error during reverse lookup operation the literal IP
|
||||
// address String will be returned.
|
||||
String literalIP = InetAddress.getByAddress(new byte[]{1, 2, 3, 4}).getCanonicalHostName();
|
||||
Assert.assertEquals(literalIP, "1.2.3.4");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import impl.DelegatingProviderImpl;
|
||||
import org.testng.Assert;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
import static impl.DelegatingProviderImpl.changeReverseLookupAddress;
|
||||
import static impl.DelegatingProviderImpl.lastReverseLookupThrowable;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary checks delegation of illegal reverse lookup request to the built-in
|
||||
* InetAddressResolver.
|
||||
* @library providers/delegating
|
||||
* @build delegating.provider/impl.DelegatingProviderImpl
|
||||
* @run testng/othervm ReverseLookupDelegationTest
|
||||
*/
|
||||
public class ReverseLookupDelegationTest {
|
||||
|
||||
@Test
|
||||
public void delegateHostNameLookupWithWrongByteArray() throws UnknownHostException {
|
||||
// The underlying resolver implementation will ignore the supplied
|
||||
// byte array and will replace it with byte array of incorrect size.
|
||||
changeReverseLookupAddress = true;
|
||||
String canonicalHostName = InetAddress.getByAddress(new byte[]{1, 2, 3, 4}).getCanonicalHostName();
|
||||
// Output canonical host name and the exception thrown by the built-in resolver
|
||||
System.err.println("Canonical host name:" + canonicalHostName);
|
||||
System.err.println("Exception thrown by the built-in resolver:" + lastReverseLookupThrowable);
|
||||
|
||||
// Check that originally supplied byte array was used to construct canonical host name after
|
||||
// failed reverse lookup.
|
||||
Assert.assertEquals("1.2.3.4", canonicalHostName, "unexpected canonical hostname");
|
||||
|
||||
// Check that on a provider side the IllegalArgumentException has been thrown by the built-in resolver
|
||||
Assert.assertTrue(lastReverseLookupThrowable instanceof IllegalArgumentException,
|
||||
"wrong exception type is thrown by the built-in resolver");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# Test data file for InetAddressResolverProvider SPI tests
|
||||
# Format: <IP address> <Host Name>
|
||||
# If multiple IP addresses are required for host:
|
||||
# multiple lines could be added
|
||||
|
||||
1.2.3.4 javaTest.org
|
||||
[ca:fe:ba:be::1] javaTest.org
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
module test.library {
|
||||
exports testlib;
|
||||
requires java.logging;
|
||||
}
|
||||
|
|
@ -0,0 +1,237 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package testlib;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.net.spi.InetAddressResolver.LookupPolicy;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import java.util.Comparator;
|
||||
|
||||
import static java.net.spi.InetAddressResolver.LookupPolicy.*;
|
||||
|
||||
public class ResolutionRegistry {
|
||||
|
||||
// Map to store hostName -> InetAddress mappings
|
||||
private final Map<String, List<byte[]>> registry;
|
||||
private static final int IPV4_RAW_LEN = 4;
|
||||
private static final int IPV6_RAW_LEN = 16;
|
||||
|
||||
private static final Logger LOGGER = Logger.getLogger(ResolutionRegistry.class.getName());
|
||||
|
||||
public ResolutionRegistry() {
|
||||
|
||||
// Populate registry from test data file
|
||||
String fileName = System.getProperty("test.dataFileName", "addresses.txt");
|
||||
Path addressesFile = Paths.get(System.getProperty("test.src", ".")).resolve(fileName);
|
||||
LOGGER.info("Creating ResolutionRegistry instance from file:" + addressesFile);
|
||||
registry = parseDataFile(addressesFile);
|
||||
}
|
||||
|
||||
private Map<String, List<byte[]>> parseDataFile(Path addressesFile) {
|
||||
try {
|
||||
if (addressesFile.toFile().isFile()) {
|
||||
Map<String, List<byte[]>> resReg = new ConcurrentHashMap<>();
|
||||
// Prepare list of hostname/address entries
|
||||
List<String[]> entriesList = Files.readAllLines(addressesFile).stream()
|
||||
.map(String::trim)
|
||||
.filter(Predicate.not(String::isBlank))
|
||||
.filter(s -> !s.startsWith("#"))
|
||||
.map(s -> s.split("\\s+"))
|
||||
.filter(sarray -> sarray.length == 2)
|
||||
.filter(ResolutionRegistry::hasLiteralAddress)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toList());
|
||||
// Convert list of entries into registry Map
|
||||
for (var entry : entriesList) {
|
||||
String ipAddress = entry[0].trim();
|
||||
String hostName = entry[1].trim();
|
||||
byte[] addrBytes = toByteArray(ipAddress);
|
||||
if (addrBytes != null) {
|
||||
var list = resReg.containsKey(hostName) ? resReg.get(hostName) : new ArrayList();
|
||||
list.add(addrBytes);
|
||||
if (!resReg.containsKey(hostName)) {
|
||||
resReg.put(hostName, list);
|
||||
}
|
||||
}
|
||||
}
|
||||
resReg.replaceAll((k, v) -> Collections.unmodifiableList(v));
|
||||
// Print constructed registry
|
||||
StringBuilder sb = new StringBuilder("Constructed addresses registry:" + System.lineSeparator());
|
||||
for (var entry : resReg.entrySet()) {
|
||||
sb.append("\t" + entry.getKey() + ": ");
|
||||
for (byte[] addr : entry.getValue()) {
|
||||
sb.append(addressBytesToString(addr) + " ");
|
||||
}
|
||||
sb.append(System.lineSeparator());
|
||||
}
|
||||
LOGGER.info(sb.toString());
|
||||
return resReg;
|
||||
} else {
|
||||
// If file doesn't exist - return empty map
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
} catch (IOException ioException) {
|
||||
// If any problems parsing the file - log a warning and return an empty map
|
||||
LOGGER.log(Level.WARNING, "Error reading data file", ioException);
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
}
|
||||
|
||||
// Line is not a blank and not a comment
|
||||
private static boolean hasLiteralAddress(String[] lineFields) {
|
||||
String addressString = lineFields[0].trim();
|
||||
return addressString.charAt(0) == '[' ||
|
||||
Character.digit(addressString.charAt(0), 16) != -1 ||
|
||||
(addressString.charAt(0) == ':');
|
||||
}
|
||||
|
||||
// Line is not blank and not comment
|
||||
private static byte[] toByteArray(String addressString) {
|
||||
InetAddress address;
|
||||
// Will reuse InetAddress functionality to parse literal IP address
|
||||
// strings. This call is guarded by 'hasLiteralAddress' method.
|
||||
try {
|
||||
address = InetAddress.getByName(addressString);
|
||||
} catch (UnknownHostException unknownHostException) {
|
||||
LOGGER.warning("Can't parse address string:'" + addressString + "'");
|
||||
return null;
|
||||
}
|
||||
return address.getAddress();
|
||||
}
|
||||
|
||||
public Stream<InetAddress> lookupHost(String host, LookupPolicy lookupPolicy)
|
||||
throws UnknownHostException {
|
||||
LOGGER.info("Looking-up '" + host + "' address");
|
||||
if (!registry.containsKey(host)) {
|
||||
LOGGER.info("Registry doesn't contain addresses for '" + host + "'");
|
||||
throw new UnknownHostException(host);
|
||||
}
|
||||
|
||||
int characteristics = lookupPolicy.characteristics();
|
||||
// Filter IPV4 or IPV6 as needed. Then sort with
|
||||
// comparator for IPV4_FIRST or IPV6_FIRST.
|
||||
return registry.get(host)
|
||||
.stream()
|
||||
.filter(ba -> filterAddressByLookupPolicy(ba, characteristics))
|
||||
.sorted(new AddressOrderPref(characteristics))
|
||||
.map(ba -> constructInetAddress(host, ba))
|
||||
.filter(Objects::nonNull);
|
||||
}
|
||||
|
||||
private static boolean filterAddressByLookupPolicy(byte[] ba, int ch) {
|
||||
// If 0011, return both. If 0001, IPv4. If 0010, IPv6
|
||||
boolean ipv4Flag = (ch & IPV4) == IPV4;
|
||||
boolean ipv6Flag = (ch & IPV6) == IPV6;
|
||||
|
||||
if (ipv4Flag && ipv6Flag)
|
||||
return true; // Return regardless of length
|
||||
else if (ipv4Flag)
|
||||
return (ba.length == IPV4_RAW_LEN);
|
||||
else if (ipv6Flag)
|
||||
return (ba.length == IPV6_RAW_LEN);
|
||||
|
||||
throw new RuntimeException("Lookup policy characteristics were improperly set. " +
|
||||
"Characteristics: " + Integer.toString(ch, 2));
|
||||
}
|
||||
|
||||
private static InetAddress constructInetAddress(String host, byte[] address) {
|
||||
try {
|
||||
return InetAddress.getByAddress(host, address);
|
||||
} catch (UnknownHostException unknownHostException) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String lookupAddress(byte[] addressBytes) {
|
||||
for (var entry : registry.entrySet()) {
|
||||
if (entry.getValue()
|
||||
.stream()
|
||||
.filter(ba -> Arrays.equals(ba, addressBytes))
|
||||
.findAny()
|
||||
.isPresent()) {
|
||||
return entry.getKey();
|
||||
}
|
||||
}
|
||||
try {
|
||||
return InetAddress.getByAddress(addressBytes).getHostAddress();
|
||||
} catch (UnknownHostException unknownHostException) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean containsAddressMapping(InetAddress address) {
|
||||
String hostName = address.getHostName();
|
||||
if (registry.containsKey(hostName)) {
|
||||
var mappedBytes = registry.get(address.getHostName());
|
||||
for (byte[] mappedAddr : mappedBytes) {
|
||||
if (Arrays.equals(mappedAddr, address.getAddress())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public static String addressBytesToString(byte[] bytes) {
|
||||
try {
|
||||
return InetAddress.getByAddress(bytes).toString();
|
||||
} catch (UnknownHostException unknownHostException) {
|
||||
return Arrays.toString(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
private class AddressOrderPref implements Comparator<byte[]> {
|
||||
|
||||
private final int ch;
|
||||
|
||||
AddressOrderPref(int ch) {
|
||||
this.ch = ch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compare(byte[] o1, byte[] o2) {
|
||||
// Compares based on address length, 4 bytes for IPv4,
|
||||
// 16 bytes for IPv6.
|
||||
return ((ch & IPV4_FIRST) == IPV4_FIRST) ?
|
||||
Integer.compare(o1.length, o2.length) :
|
||||
Integer.compare(o2.length, o1.length);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
networkaddress.cache.ttl=7
|
||||
networkaddress.cache.negative.ttl=3
|
||||
networkaddress.cache.stale.ttl=30
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
networkaddress.cache.ttl=-1
|
||||
networkaddress.cache.negative.ttl=-1
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
networkaddress.cache.ttl=-1
|
||||
networkaddress.cache.negative.ttl=-1
|
||||
networkaddress.cache.stale.ttl=-1
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
networkaddress.cache.ttl=-1
|
||||
networkaddress.cache.negative.ttl=-1
|
||||
networkaddress.cache.stale.ttl=10000
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
networkaddress.cache.ttl=-1
|
||||
networkaddress.cache.negative.ttl=-1
|
||||
networkaddress.cache.stale.ttl=0
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
networkaddress.cache.ttl=0
|
||||
networkaddress.cache.negative.ttl=0
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
networkaddress.cache.ttl=0
|
||||
networkaddress.cache.negative.ttl=0
|
||||
networkaddress.cache.stale.ttl=-1
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
networkaddress.cache.ttl=0
|
||||
networkaddress.cache.negative.ttl=0
|
||||
networkaddress.cache.stale.ttl=10000
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
networkaddress.cache.ttl=0
|
||||
networkaddress.cache.negative.ttl=0
|
||||
networkaddress.cache.stale.ttl=0
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package impl;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.net.spi.InetAddressResolver;
|
||||
import java.net.spi.InetAddressResolverProvider;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class WithBootstrapResolverUsageProvider extends InetAddressResolverProvider {
|
||||
|
||||
public static volatile long numberOfGetCalls;
|
||||
|
||||
@Override
|
||||
public InetAddressResolver get(Configuration configuration) {
|
||||
numberOfGetCalls++;
|
||||
System.out.println("The following provider will be used by current test:" +
|
||||
this.getClass().getCanonicalName());
|
||||
System.out.println("InetAddressResolverProvider::get() called " + numberOfGetCalls + " times");
|
||||
|
||||
// We use different names to avoid InetAddress-level caching
|
||||
doLookup("foo" + numberOfGetCalls + ".A.org");
|
||||
|
||||
// We need second call to test how InetAddress internals maintain reference to a bootstrap resolver
|
||||
doLookup("foo" + numberOfGetCalls + ".B.org");
|
||||
|
||||
return new InetAddressResolver() {
|
||||
@Override
|
||||
public Stream<InetAddress> lookupByName(String host, LookupPolicy lookupPolicy)
|
||||
throws UnknownHostException {
|
||||
return Stream.of(InetAddress.getByAddress(host, new byte[]{127, 0, 2, 1}));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String lookupByAddress(byte[] addr) throws UnknownHostException {
|
||||
return configuration.builtinResolver().lookupByAddress(addr);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Perform an InetAddress resolution lookup operation
|
||||
private static void doLookup(String hostName) {
|
||||
try {
|
||||
InetAddress.getByName(hostName);
|
||||
} catch (UnknownHostException e) {
|
||||
// Ignore UHE since the bootstrap resolver is used here
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "WithBootstrapResolverUsageProvider";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.net.spi.InetAddressResolverProvider;
|
||||
|
||||
module bootstrap.usage.provider {
|
||||
exports impl;
|
||||
requires java.logging;
|
||||
provides InetAddressResolverProvider with impl.WithBootstrapResolverUsageProvider;
|
||||
}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package impl;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.net.spi.InetAddressResolver;
|
||||
import java.net.spi.InetAddressResolverProvider;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class DelegatingProviderImpl extends InetAddressResolverProvider {
|
||||
|
||||
public static volatile boolean changeReverseLookupAddress;
|
||||
public static volatile Throwable lastReverseLookupThrowable;
|
||||
|
||||
@Override
|
||||
public InetAddressResolver get(Configuration configuration) {
|
||||
System.out.println("The following provider will be used by current test:" +
|
||||
this.getClass().getCanonicalName());
|
||||
return new InetAddressResolver() {
|
||||
@Override
|
||||
public Stream<InetAddress> lookupByName(String host, LookupPolicy lookupPolicy) throws UnknownHostException {
|
||||
return configuration.builtinResolver().lookupByName(host, lookupPolicy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String lookupByAddress(byte[] addr) throws UnknownHostException {
|
||||
try {
|
||||
if (!changeReverseLookupAddress) {
|
||||
return configuration.builtinResolver().lookupByAddress(addr);
|
||||
} else {
|
||||
// Deliberately supply address bytes array with wrong size
|
||||
return configuration.builtinResolver().lookupByAddress(new byte[]{1, 2, 3});
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
lastReverseLookupThrowable = t;
|
||||
throw t;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "DelegatingProvider";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.net.spi.InetAddressResolverProvider;
|
||||
|
||||
module delegating.provider {
|
||||
exports impl;
|
||||
provides InetAddressResolverProvider with impl.DelegatingProviderImpl;
|
||||
}
|
||||
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package impl;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.net.spi.InetAddressResolver;
|
||||
import java.net.spi.InetAddressResolverProvider;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class EmptyResultsProviderImpl extends InetAddressResolverProvider {
|
||||
@Override
|
||||
public InetAddressResolver get(Configuration configuration) {
|
||||
System.out.println("The following provider will be used by current test:" +
|
||||
this.getClass().getCanonicalName());
|
||||
|
||||
return new InetAddressResolver() {
|
||||
@Override
|
||||
public Stream<InetAddress> lookupByName(String host, LookupPolicy lookupPolicy)
|
||||
throws UnknownHostException {
|
||||
return Stream.empty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String lookupByAddress(byte[] addr) throws UnknownHostException {
|
||||
return configuration.builtinResolver().lookupByAddress(addr);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "EmptyForwardLookupResultsProvider";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.net.spi.InetAddressResolverProvider;
|
||||
|
||||
module empty.results.provider {
|
||||
exports impl;
|
||||
provides InetAddressResolverProvider with impl.EmptyResultsProviderImpl;
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package impl;
|
||||
|
||||
import java.net.spi.InetAddressResolverProvider;
|
||||
import java.net.spi.InetAddressResolver;
|
||||
|
||||
public class FaultyResolverProviderGetImpl extends InetAddressResolverProvider {
|
||||
public static final String EXCEPTION_MESSAGE = "This provider provides nothing";
|
||||
|
||||
@Override
|
||||
public InetAddressResolver get(Configuration configuration) {
|
||||
System.out.println("The following provider will be used by current test:" + this.getClass().getCanonicalName());
|
||||
throw new IllegalArgumentException(EXCEPTION_MESSAGE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "faultyInetAddressResolverGet";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.net.spi.InetAddressResolverProvider;
|
||||
|
||||
module faulty.provider {
|
||||
exports impl;
|
||||
requires java.logging;
|
||||
provides InetAddressResolverProvider with impl.FaultyResolverProviderGetImpl;
|
||||
}
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package impl;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.net.spi.InetAddressResolver;
|
||||
import java.net.spi.InetAddressResolverProvider;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class InetAddressUsageInGetProviderImpl extends InetAddressResolverProvider {
|
||||
@Override
|
||||
public InetAddressResolver get(Configuration configuration) {
|
||||
System.out.println("The following provider will be used by current test:" + this.getClass().getCanonicalName());
|
||||
String localHostName;
|
||||
try {
|
||||
localHostName = InetAddress.getLocalHost().getHostName();
|
||||
} catch (UnknownHostException e) {
|
||||
throw new RuntimeException("Provider failed to initialize");
|
||||
}
|
||||
return new InetAddressResolver() {
|
||||
@Override
|
||||
public Stream<InetAddress> lookupByName(String host, LookupPolicy lookupPolicy) throws UnknownHostException {
|
||||
if (host.equals(localHostName)) {
|
||||
return configuration.builtinResolver().lookupByName(host, lookupPolicy);
|
||||
} else {
|
||||
throw new UnknownHostException(host);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String lookupByAddress(byte[] addr) throws UnknownHostException {
|
||||
return configuration.builtinResolver().lookupByAddress(addr);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "ProviderWithInetAddressUsageInGet";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.net.spi.InetAddressResolverProvider;
|
||||
|
||||
module recursive.init.provider {
|
||||
exports impl;
|
||||
requires java.logging;
|
||||
provides InetAddressResolverProvider with impl.InetAddressUsageInGetProviderImpl;
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
* Copyright (c) 2021, 2023, 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.
|
||||
*/
|
||||
|
||||
package impl;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.net.spi.InetAddressResolver;
|
||||
import java.net.spi.InetAddressResolver.LookupPolicy;
|
||||
import java.net.spi.InetAddressResolverProvider;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import testlib.ResolutionRegistry;
|
||||
|
||||
public class SimpleResolverProviderImpl extends InetAddressResolverProvider {
|
||||
|
||||
public static ResolutionRegistry registry = new ResolutionRegistry();
|
||||
private static List<LookupPolicy> LOOKUP_HISTORY = Collections.synchronizedList(new ArrayList<>());
|
||||
private static volatile long LAST_LOOKUP_TIMESTAMP;
|
||||
private static volatile boolean unreachableServer;
|
||||
private static volatile CountDownLatch blocker;
|
||||
private static Logger LOGGER = Logger.getLogger(SimpleResolverProviderImpl.class.getName());
|
||||
|
||||
@Override
|
||||
public InetAddressResolver get(Configuration configuration) {
|
||||
System.out.println("The following provider will be used by current test:" + this.getClass().getCanonicalName());
|
||||
return new InetAddressResolver() {
|
||||
@Override
|
||||
public Stream<InetAddress> lookupByName(String host, LookupPolicy lookupPolicy) throws UnknownHostException {
|
||||
LOGGER.info("Looking-up addresses for '" + host + "'. Lookup characteristics:" +
|
||||
Integer.toString(lookupPolicy.characteristics(), 2));
|
||||
if (blocker != null) {
|
||||
try {
|
||||
blocker.await();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
LOOKUP_HISTORY.add(lookupPolicy);
|
||||
LAST_LOOKUP_TIMESTAMP = System.nanoTime();
|
||||
if (unreachableServer) {
|
||||
throw new UnknownHostException("unreachableServer");
|
||||
}
|
||||
return registry.lookupHost(host, lookupPolicy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String lookupByAddress(byte[] addr) throws UnknownHostException {
|
||||
LOGGER.info("Looking host name for the following address:" + ResolutionRegistry.addressBytesToString(addr));
|
||||
if (unreachableServer) {
|
||||
throw new UnknownHostException("unreachableServer");
|
||||
}
|
||||
return registry.lookupAddress(addr);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// Utility methods
|
||||
public static LookupPolicy lastLookupPolicy() {
|
||||
return lookupPolicyHistory(0);
|
||||
}
|
||||
|
||||
public static long getLastLookupTimestamp() {
|
||||
return LAST_LOOKUP_TIMESTAMP;
|
||||
}
|
||||
|
||||
public static void setUnreachableServer(boolean unreachableServer) {
|
||||
SimpleResolverProviderImpl.unreachableServer = unreachableServer;
|
||||
}
|
||||
|
||||
public static void setBlocker(CountDownLatch blocker) {
|
||||
SimpleResolverProviderImpl.blocker = blocker;
|
||||
}
|
||||
|
||||
public static LookupPolicy lookupPolicyHistory(int position) {
|
||||
if (LOOKUP_HISTORY.isEmpty()) {
|
||||
throw new RuntimeException("No registered lookup policies");
|
||||
}
|
||||
if (position >= LOOKUP_HISTORY.size()) {
|
||||
throw new IllegalArgumentException("No element available with provided position");
|
||||
}
|
||||
return LOOKUP_HISTORY.get(LOOKUP_HISTORY.size() - position - 1);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "simpleInetAddressResolver";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.net.spi.InetAddressResolverProvider;
|
||||
|
||||
module simple.provider {
|
||||
exports impl;
|
||||
requires java.logging;
|
||||
requires test.library;
|
||||
provides InetAddressResolverProvider with impl.SimpleResolverProviderImpl;
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package impl;
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.net.spi.InetAddressResolver;
|
||||
import java.net.spi.InetAddressResolverProvider;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
public class ThrowingLookupsProviderImpl extends InetAddressResolverProvider {
|
||||
@Override
|
||||
public InetAddressResolver get(Configuration configuration) {
|
||||
System.out.println("The following provider will be used by current test:" +
|
||||
this.getClass().getCanonicalName());
|
||||
|
||||
return new InetAddressResolver() {
|
||||
@Override
|
||||
public Stream<InetAddress> lookupByName(String host, LookupPolicy lookupPolicy)
|
||||
throws UnknownHostException {
|
||||
if (throwRuntimeException) {
|
||||
System.err.println(name()+" forward lookup: throwing RuntimeException");
|
||||
throw new RuntimeException(RUNTIME_EXCEPTION_MESSAGE);
|
||||
} else {
|
||||
System.err.println(name()+" forward lookup: throwing UnknownHostException");
|
||||
throw new UnknownHostException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String lookupByAddress(byte[] addr) throws UnknownHostException {
|
||||
if (throwRuntimeException) {
|
||||
System.err.println(name()+" reverse lookup: throwing RuntimeException");
|
||||
throw new RuntimeException(RUNTIME_EXCEPTION_MESSAGE);
|
||||
} else {
|
||||
System.err.println(name()+" reverse lookup: throwing UnknownHostException");
|
||||
throw new UnknownHostException();
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "ThrowingLookupsProvider";
|
||||
}
|
||||
|
||||
// Indicates if provider need to throw RuntimeException for forward and reverse lookup operations.
|
||||
// If it is set to 'false' then UnknownHostException will thrown for each operation.
|
||||
public static volatile boolean throwRuntimeException;
|
||||
public static final String RUNTIME_EXCEPTION_MESSAGE = "This provider only throws exceptions";
|
||||
}
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.net.spi.InetAddressResolverProvider;
|
||||
|
||||
module throwing.lookups.provider {
|
||||
exports impl;
|
||||
provides InetAddressResolverProvider with impl.ThrowingLookupsProviderImpl;
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
import static org.testng.Assert.assertThrows;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Test that InetAddressResolverProvider implementation can be installed to a class path.
|
||||
* @library ../../lib
|
||||
* @build test.library/testlib.ResolutionRegistry ClasspathResolverProviderImpl
|
||||
* @run testng/othervm ClasspathProviderTest
|
||||
*/
|
||||
|
||||
public class ClasspathProviderTest {
|
||||
|
||||
@Test
|
||||
public void testResolution() throws Exception {
|
||||
InetAddress inetAddress = InetAddress.getByName("classpath-provider-test.org");
|
||||
System.err.println("Resolved address:" + inetAddress);
|
||||
|
||||
if (!ClasspathResolverProviderImpl.registry.containsAddressMapping(inetAddress)) {
|
||||
throw new RuntimeException("InetAddressResolverProvider was not properly installed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
import java.net.spi.InetAddressResolverProvider;
|
||||
import java.net.spi.InetAddressResolver;
|
||||
import java.net.spi.InetAddressResolver.LookupPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import testlib.ResolutionRegistry;
|
||||
|
||||
public class ClasspathResolverProviderImpl extends InetAddressResolverProvider {
|
||||
|
||||
public static ResolutionRegistry registry = new ResolutionRegistry();
|
||||
private static List<LookupPolicy> LOOKUP_HISTORY = Collections.synchronizedList(new ArrayList<>());
|
||||
private static Logger LOGGER = Logger.getLogger(ClasspathResolverProviderImpl.class.getName());
|
||||
|
||||
@Override
|
||||
public InetAddressResolver get(Configuration configuration) {
|
||||
System.out.println("The following provider will be used by current test:" + this.getClass().getCanonicalName());
|
||||
return new InetAddressResolver() {
|
||||
@Override
|
||||
public Stream<InetAddress> lookupByName(String host, LookupPolicy lookupPolicy) throws UnknownHostException {
|
||||
LOGGER.info("Looking-up addresses for '" + host + "'. Lookup characteristics:" +
|
||||
Integer.toString(lookupPolicy.characteristics(), 2));
|
||||
LOOKUP_HISTORY.add(lookupPolicy);
|
||||
return registry.lookupHost(host, lookupPolicy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String lookupByAddress(byte[] addr) throws UnknownHostException {
|
||||
LOGGER.info("Looking host name for the following address:" + ResolutionRegistry.addressBytesToString(addr));
|
||||
return registry.lookupAddress(addr);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public String name() {
|
||||
return "classpathINSP";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
ClasspathResolverProviderImpl
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# Test data file for classpath origin type tests.
|
||||
# Format: <IP address> <Host Name>
|
||||
# If multiple IP addresses are required for host:
|
||||
# multiple lines could be added
|
||||
|
||||
1.2.3.4 classpath-provider-test.org
|
||||
[ca:fe:ba:be::1] classpath-provider-test.org
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import java.net.InetAddress;
|
||||
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @summary Test that implementation of InetAddressResolverProvider can be installed to a module path.
|
||||
* @library ../../lib ../../providers/simple
|
||||
* @build test.library/testlib.ResolutionRegistry simple.provider/impl.SimpleResolverProviderImpl
|
||||
* ModularProviderTest
|
||||
* @run testng/othervm ModularProviderTest
|
||||
*/
|
||||
|
||||
|
||||
public class ModularProviderTest {
|
||||
|
||||
@Test
|
||||
public void testResolution() throws Exception {
|
||||
InetAddress inetAddress = InetAddress.getByName("modular-provider-test.org");
|
||||
System.err.println("Resolved address:" + inetAddress);
|
||||
|
||||
if (!impl.SimpleResolverProviderImpl.registry.containsAddressMapping(inetAddress)) {
|
||||
throw new RuntimeException("InetAddressResolverProvider was not properly installed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
# Test data file for tests in modularTests directory
|
||||
# Format: <IP address> <Host Name>
|
||||
# If multiple IP addresses are required for host:
|
||||
# multiple lines could be added
|
||||
|
||||
1.2.3.4 modular-provider-test.org
|
||||
[ca:fe:ba:be::1] modular-provider-test.org
|
||||
336
test/jdk/java/net/spi/URLStreamHandlerProvider/Basic.java
Normal file
336
test/jdk/java/net/spi/URLStreamHandlerProvider/Basic.java
Normal file
|
|
@ -0,0 +1,336 @@
|
|||
/*
|
||||
* Copyright (c) 2015, 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.
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.Reader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.SequenceInputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javax.tools.JavaCompiler;
|
||||
import javax.tools.JavaFileObject;
|
||||
import javax.tools.StandardJavaFileManager;
|
||||
import javax.tools.StandardLocation;
|
||||
import javax.tools.ToolProvider;
|
||||
|
||||
import jdk.test.lib.process.ProcessTools;
|
||||
import jdk.test.lib.util.FileUtils;
|
||||
import jdk.test.lib.JDKToolFinder;
|
||||
import static java.lang.String.format;
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8064924
|
||||
* @modules jdk.compiler
|
||||
* @summary Basic test for URLStreamHandlerProvider
|
||||
* @library /test/lib
|
||||
* @build jdk.test.lib.Platform
|
||||
* jdk.test.lib.util.FileUtils
|
||||
* jdk.test.lib.JDKToolFinder
|
||||
* @compile Basic.java Child.java
|
||||
* @run main Basic
|
||||
*/
|
||||
|
||||
public class Basic {
|
||||
|
||||
static final Path TEST_SRC = Paths.get(System.getProperty("test.src", "."));
|
||||
static final Path TEST_CLASSES = Paths.get(System.getProperty("test.classes", "."));
|
||||
|
||||
public static void main(String[] args) throws Throwable {
|
||||
unknownProtocol("foo", UNKNOWN);
|
||||
unknownProtocol("bar", UNKNOWN);
|
||||
viaProvider("baz", KNOWN);
|
||||
viaProvider("bert", KNOWN);
|
||||
viaBadProvider("tom", SCE);
|
||||
viaBadProvider("jerry", SCE);
|
||||
viaCircularProvider("circular", CIRCULAR);
|
||||
}
|
||||
|
||||
private static String withoutWarning(String in) {
|
||||
return in.lines().filter(s -> !s.startsWith("WARNING:")).collect(Collectors.joining());
|
||||
}
|
||||
|
||||
static final Consumer<Result> KNOWN = r -> {
|
||||
if (r.exitValue != 0 || !withoutWarning(r.output).isEmpty())
|
||||
throw new RuntimeException("[" + r.output + "]");
|
||||
};
|
||||
static final Consumer<Result> UNKNOWN = r -> {
|
||||
if (r.exitValue == 0 ||
|
||||
!r.output.contains("java.net.MalformedURLException: unknown protocol")) {
|
||||
throw new RuntimeException("exitValue: "+ r.exitValue + ", output:[" +r.output +"]");
|
||||
}
|
||||
};
|
||||
static final Consumer<Result> SCE = r -> {
|
||||
if (r.exitValue == 0 ||
|
||||
!r.output.contains("java.util.ServiceConfigurationError")) {
|
||||
throw new RuntimeException("exitValue: "+ r.exitValue + ", output:[" +r.output +"]");
|
||||
}
|
||||
};
|
||||
static final Consumer<Result> CIRCULAR = r -> {
|
||||
if (r.exitValue == 0 ||
|
||||
!r.output.contains("Circular loading of URL stream handler providers detected")) {
|
||||
throw new RuntimeException("exitValue: " + r.exitValue + ", output:[" + r.output + "]");
|
||||
}
|
||||
};
|
||||
|
||||
static void unknownProtocol(String protocol, Consumer<Result> resultChecker) {
|
||||
System.out.println("\nTesting " + protocol);
|
||||
Result r = java(Collections.emptyList(), asList(TEST_CLASSES),
|
||||
"Child", protocol);
|
||||
resultChecker.accept(r);
|
||||
}
|
||||
|
||||
static void viaProvider(String protocol, Consumer<Result> resultChecker,
|
||||
String... sysProps)
|
||||
throws Exception
|
||||
{
|
||||
viaProviderWithTemplate(protocol, resultChecker,
|
||||
TEST_SRC.resolve("provider.template"),
|
||||
sysProps);
|
||||
}
|
||||
|
||||
static void viaBadProvider(String protocol, Consumer<Result> resultChecker,
|
||||
String... sysProps)
|
||||
throws Exception
|
||||
{
|
||||
viaProviderWithTemplate(protocol, resultChecker,
|
||||
TEST_SRC.resolve("bad.provider.template"),
|
||||
sysProps);
|
||||
}
|
||||
|
||||
static void viaCircularProvider(String protocol, Consumer<Result> resultChecker,
|
||||
String... sysProps)
|
||||
throws Exception
|
||||
{
|
||||
viaProviderWithTemplate(protocol, resultChecker,
|
||||
TEST_SRC.resolve("circular.provider.template"),
|
||||
sysProps);
|
||||
}
|
||||
|
||||
static void viaProviderWithTemplate(String protocol,
|
||||
Consumer<Result> resultChecker,
|
||||
Path template, String... sysProps)
|
||||
throws Exception
|
||||
{
|
||||
System.out.println("\nTesting " + protocol);
|
||||
Path testRoot = Paths.get("URLStreamHandlerProvider-" + protocol);
|
||||
if (Files.exists(testRoot))
|
||||
FileUtils.deleteFileTreeWithRetry(testRoot);
|
||||
Files.createDirectory(testRoot);
|
||||
|
||||
Path srcPath = Files.createDirectory(testRoot.resolve("src"));
|
||||
Path srcClass = createProvider(protocol, template, srcPath);
|
||||
|
||||
Path build = Files.createDirectory(testRoot.resolve("build"));
|
||||
javac(build, srcClass);
|
||||
createServices(build, protocol);
|
||||
Path testJar = testRoot.resolve("test.jar");
|
||||
jar(testJar, build);
|
||||
|
||||
List<String> props = new ArrayList<>();
|
||||
for (String p : sysProps)
|
||||
props.add(p);
|
||||
|
||||
Result r = java(props, asList(testJar, TEST_CLASSES),
|
||||
"Child", protocol);
|
||||
|
||||
resultChecker.accept(r);
|
||||
}
|
||||
|
||||
static String platformPath(String p) { return p.replace("/", File.separator); }
|
||||
static String binaryName(String name) { return name.replace(".", "/"); }
|
||||
|
||||
static final String SERVICE_IMPL_PREFIX = "net.java.openjdk.test";
|
||||
|
||||
static void createServices(Path dst, String protocol) throws IOException {
|
||||
Path services = Files.createDirectories(dst.resolve("META-INF")
|
||||
.resolve("services"));
|
||||
|
||||
final String implName = SERVICE_IMPL_PREFIX + "." + protocol + ".Provider";
|
||||
Path s = services.resolve("java.net.spi.URLStreamHandlerProvider");
|
||||
FileWriter fw = new FileWriter(s.toFile());
|
||||
try {
|
||||
fw.write(implName);
|
||||
} finally {
|
||||
fw.close();
|
||||
}
|
||||
}
|
||||
|
||||
static Path createProvider(String protocol, Path srcTemplate, Path dst)
|
||||
throws IOException
|
||||
{
|
||||
String pkg = SERVICE_IMPL_PREFIX + "." + protocol;
|
||||
Path classDst = dst.resolve(platformPath(binaryName(pkg)));
|
||||
Files.createDirectories(classDst);
|
||||
Path classPath = classDst.resolve("Provider.java");
|
||||
|
||||
List<String> lines = Files.lines(srcTemplate)
|
||||
.map(s -> s.replaceAll("\\$package", pkg))
|
||||
.map(s -> s.replaceAll("\\$protocol", protocol))
|
||||
.collect(Collectors.toList());
|
||||
Files.write(classPath, lines);
|
||||
|
||||
return classPath;
|
||||
}
|
||||
|
||||
static void jar(Path jarName, Path jarRoot) { String jar = getJDKTool("jar");
|
||||
ProcessBuilder p = new ProcessBuilder(jar, "cf", jarName.toString(),
|
||||
"-C", jarRoot.toString(), ".");
|
||||
quickFail(run(p));
|
||||
}
|
||||
|
||||
static void javac(Path dest, Path... sourceFiles) throws IOException {
|
||||
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
|
||||
try (StandardJavaFileManager fileManager =
|
||||
compiler.getStandardFileManager(null, null, null)) {
|
||||
|
||||
List<File> files = Stream.of(sourceFiles)
|
||||
.map(p -> p.toFile())
|
||||
.collect(Collectors.toList());
|
||||
List<File> dests = Stream.of(dest)
|
||||
.map(p -> p.toFile())
|
||||
.collect(Collectors.toList());
|
||||
Iterable<? extends JavaFileObject> compilationUnits =
|
||||
fileManager.getJavaFileObjectsFromFiles(files);
|
||||
fileManager.setLocation(StandardLocation.CLASS_OUTPUT, dests);
|
||||
JavaCompiler.CompilationTask task =
|
||||
compiler.getTask(null, fileManager, null, null, null, compilationUnits);
|
||||
boolean passed = task.call();
|
||||
if (!passed)
|
||||
throw new RuntimeException("Error compiling " + files);
|
||||
}
|
||||
}
|
||||
|
||||
static void quickFail(Result r) {
|
||||
if (r.exitValue != 0)
|
||||
throw new RuntimeException(r.output);
|
||||
}
|
||||
|
||||
static Result java(List<String> sysProps, Collection<Path> classpath,
|
||||
String classname, String arg) {
|
||||
|
||||
List<String> commands = new ArrayList<>(sysProps);
|
||||
|
||||
String cp = classpath.stream()
|
||||
.map(Path::toString)
|
||||
.collect(Collectors.joining(File.pathSeparator));
|
||||
commands.add("-cp");
|
||||
commands.add(cp);
|
||||
commands.add(classname);
|
||||
commands.add(arg);
|
||||
|
||||
return run(ProcessTools.createTestJavaProcessBuilder(commands));
|
||||
}
|
||||
|
||||
static Result run(ProcessBuilder pb) {
|
||||
Process p = null;
|
||||
System.out.println("running: " + pb.command());
|
||||
try {
|
||||
p = pb.start();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(
|
||||
format("Couldn't start process '%s'", pb.command()), e);
|
||||
}
|
||||
|
||||
String output;
|
||||
try {
|
||||
output = toString(p.getInputStream(), p.getErrorStream());
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(
|
||||
format("Couldn't read process output '%s'", pb.command()), e);
|
||||
}
|
||||
|
||||
try {
|
||||
p.waitFor();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException(
|
||||
format("Process hasn't finished '%s'", pb.command()), e);
|
||||
}
|
||||
|
||||
return new Result(p.exitValue(), output);
|
||||
}
|
||||
|
||||
static final String DEFAULT_IMAGE_BIN = System.getProperty("java.home")
|
||||
+ File.separator + "bin" + File.separator;
|
||||
|
||||
static String getJDKTool(String name) {
|
||||
try {
|
||||
return JDKToolFinder.getJDKTool(name);
|
||||
} catch (Exception x) {
|
||||
return DEFAULT_IMAGE_BIN + name;
|
||||
}
|
||||
}
|
||||
|
||||
static String toString(InputStream... src) throws IOException {
|
||||
StringWriter dst = new StringWriter();
|
||||
Reader concatenated =
|
||||
new InputStreamReader(
|
||||
new SequenceInputStream(
|
||||
Collections.enumeration(asList(src))));
|
||||
copy(concatenated, dst);
|
||||
return dst.toString();
|
||||
}
|
||||
|
||||
static void copy(Reader src, Writer dst) throws IOException {
|
||||
int len;
|
||||
char[] buf = new char[1024];
|
||||
try {
|
||||
while ((len = src.read(buf)) != -1)
|
||||
dst.write(buf, 0, len);
|
||||
} finally {
|
||||
try {
|
||||
src.close();
|
||||
} catch (IOException ignored1) {
|
||||
} finally {
|
||||
try {
|
||||
dst.close();
|
||||
} catch (IOException ignored2) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static class Result {
|
||||
final int exitValue;
|
||||
final String output;
|
||||
|
||||
private Result(int exitValue, String output) {
|
||||
this.exitValue = exitValue;
|
||||
this.output = output;
|
||||
}
|
||||
}
|
||||
}
|
||||
45
test/jdk/java/net/spi/URLStreamHandlerProvider/Child.java
Normal file
45
test/jdk/java/net/spi/URLStreamHandlerProvider/Child.java
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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;
|
||||
|
||||
public class Child {
|
||||
|
||||
public static void main(String[] args) throws MalformedURLException {
|
||||
if (args.length != 1) {
|
||||
System.err.println("Usage: java Child <protocol>");
|
||||
return;
|
||||
}
|
||||
String protocol = args[0];
|
||||
URL url = new URL(protocol + "://");
|
||||
|
||||
// toExternalForm should return the protocol string
|
||||
String s = url.toExternalForm();
|
||||
if (!s.equals(protocol)) {
|
||||
System.err.println("Expected url.toExternalForm to return "
|
||||
+ protocol + ", but got: " + s);
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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 $package;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.net.spi.URLStreamHandlerProvider;
|
||||
|
||||
public class Provider extends URLStreamHandlerProvider {
|
||||
|
||||
public Provider(String someRandomArg) { // No no-args constructor
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URLStreamHandler createURLStreamHandler(String protocol) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
|
||||
package $package;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.net.spi.URLStreamHandlerProvider;
|
||||
|
||||
public final class Provider extends URLStreamHandlerProvider {
|
||||
|
||||
private static final String PROTOCOL = "$protocol";
|
||||
|
||||
@Override
|
||||
public URLStreamHandler createURLStreamHandler(String protocol) {
|
||||
try {
|
||||
// Trigger circular lookup
|
||||
URI.create("bogus://path/to/nothing").toURL();
|
||||
} catch (Exception exception) {
|
||||
throw new RuntimeException(exception);
|
||||
}
|
||||
throw new AssertionError("Should not have reached here!");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* 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.
|
||||
*
|
||||
* 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 $package;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.net.URLStreamHandler;
|
||||
import java.net.spi.URLStreamHandlerProvider;
|
||||
|
||||
public class Provider extends URLStreamHandlerProvider {
|
||||
|
||||
private static final String PROTOCOL = "$protocol";
|
||||
|
||||
@Override
|
||||
public URLStreamHandler createURLStreamHandler(String protocol) {
|
||||
if (!PROTOCOL.equals(protocol))
|
||||
return null;
|
||||
|
||||
return new Handler();
|
||||
}
|
||||
|
||||
static class Handler extends URLStreamHandler {
|
||||
public URLConnection openConnection(URL u) throws java.io.IOException {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String toExternalForm(URL u) { return PROTOCOL; }
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue