diff --git a/api/src/main/java/io/grpc/ServerRegistry.java b/api/src/main/java/io/grpc/ServerRegistry.java index e6a067ce87..70fd365730 100644 --- a/api/src/main/java/io/grpc/ServerRegistry.java +++ b/api/src/main/java/io/grpc/ServerRegistry.java @@ -23,6 +23,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.LinkedHashSet; import java.util.List; +import java.util.logging.Level; import java.util.logging.Logger; import javax.annotation.concurrent.GuardedBy; import javax.annotation.concurrent.ThreadSafe; @@ -92,7 +93,7 @@ public final class ServerRegistry { if (instance == null) { List providerList = ServiceProviders.loadAll( ServerProvider.class, - Collections.>emptyList(), + getHardCodedClasses(), ServerProvider.class.getClassLoader(), new ServerPriorityAccessor()); instance = new ServerRegistry(); @@ -119,6 +120,20 @@ public final class ServerRegistry { return providers.isEmpty() ? null : providers.get(0); } + @VisibleForTesting + static List> getHardCodedClasses() { + // Class.forName(String) is used to remove the need for ProGuard configuration. Note that + // ProGuard does not detect usages of Class.forName(String, boolean, ClassLoader): + // https://sourceforge.net/p/proguard/bugs/418/ + List> list = new ArrayList<>(); + try { + list.add(Class.forName("io.grpc.okhttp.OkHttpServerProvider")); + } catch (ClassNotFoundException e) { + logger.log(Level.FINE, "Unable to find OkHttpServerProvider", e); + } + return Collections.unmodifiableList(list); + } + ServerBuilder newServerBuilderForPort(int port, ServerCredentials creds) { List providers = providers(); if (providers.isEmpty()) { diff --git a/api/src/testFixtures/java/io/grpc/ServerRegistryAccessor.java b/api/src/testFixtures/java/io/grpc/ServerRegistryAccessor.java new file mode 100644 index 0000000000..b15d4dfde1 --- /dev/null +++ b/api/src/testFixtures/java/io/grpc/ServerRegistryAccessor.java @@ -0,0 +1,26 @@ +/* + * Copyright 2023 The gRPC Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.grpc; + +/** Accesses test-only methods of {@link ServerRegistry}. */ +public final class ServerRegistryAccessor { + private ServerRegistryAccessor() {} + + public static Iterable> getHardCodedClasses() { + return ServerRegistry.getHardCodedClasses(); + } +} diff --git a/okhttp/build.gradle b/okhttp/build.gradle index 7d84df436d..99f799ec97 100644 --- a/okhttp/build.gradle +++ b/okhttp/build.gradle @@ -50,6 +50,7 @@ tasks.named("checkstyleMain").configure { tasks.named("javadoc").configure { options.links 'http://square.github.io/okhttp/2.x/okhttp/' exclude 'io/grpc/okhttp/Internal*' + exclude 'io/grpc/okhttp/*Provider.java' exclude 'io/grpc/okhttp/internal/**' } diff --git a/okhttp/src/main/java/io/grpc/okhttp/OkHttpServerBuilder.java b/okhttp/src/main/java/io/grpc/okhttp/OkHttpServerBuilder.java index 45d6b9efc5..8269a8ddf0 100644 --- a/okhttp/src/main/java/io/grpc/okhttp/OkHttpServerBuilder.java +++ b/okhttp/src/main/java/io/grpc/okhttp/OkHttpServerBuilder.java @@ -18,7 +18,6 @@ package io.grpc.okhttp; import static com.google.common.base.Preconditions.checkArgument; -import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; import com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.errorprone.annotations.DoNotCall; @@ -89,7 +88,7 @@ public final class OkHttpServerBuilder extends ForwardingServerBuilder provider.builderForPort(80)); + } + + @Test + public void newServerBuilderForPort_success() { + ServerProvider.NewServerBuilderResult result = + provider.newServerBuilderForPort(80, InsecureServerCredentials.create()); + assertThat(result.getServerBuilder()).isInstanceOf(OkHttpServerBuilder.class); + } + + @Test + public void newServerBuilderForPort_fail() { + ServerProvider.NewServerBuilderResult result = provider.newServerBuilderForPort( + 80, new FakeServerCredentials()); + assertThat(result.getError()).contains("FakeServerCredentials"); + } + + private static final class FakeServerCredentials extends ServerCredentials {} +}