Skip to content

Commit 24241c9

Browse files
authored
test: Disable copying annotation on mocks for Java 8 CIs (#13702)
In JSpecify 1.0.0, the `@NullMarked` annotation includes `ElementType.MODULE` in its `@Target` metadata. Because `ElementType.MODULE` was introduced in Java 9, reflecting on `@NullMarked` classes under Java 8 (JDK 1.8) throws `EnumConstantNotPresentExceptionProxy` wrapped in an `ArrayStoreException`. When unit tests run on Java 8, Mockito's default mock generation (via ByteBuddy) attempts to copy all runtime class annotations from target classes onto mock subclasses. This triggers the reflection crash when mocking generated stub and settings classes that are annotated with `@NullMarked`. To bypass this Java 8 limitation: - Replaced default Mockito mock instantiation with `Mockito.mock(Class, Mockito.withSettings().withoutAnnotations())` across the failing unit test suites. - Disabling annotation copying prevents Mockito/ByteBuddy from invoking `Class.getAnnotations()` on the target class during proxy creation, allowing tests to run and mock stubs successfully on Java 8 pipelines. Modified Mockito mock setups in: - `StreamingSubscriberConnectionTest` - `SpannerImplTest` - `SpannerCloudMonitoringExporterTest` - `BigtableInstanceAdminClientV2Test` - `BigtableTableAdminClientV2Test` - `BigtableCloudMonitoringExporterTest` - `GrpcLongRunningClientTest`
1 parent 087ea90 commit 24241c9

5 files changed

Lines changed: 67 additions & 44 deletions

File tree

java-bigtable/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/admin/v2/BigtableTableAdminClientV2Test.java

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,28 +31,22 @@
3131
import java.util.concurrent.Executor;
3232
import java.util.concurrent.atomic.AtomicBoolean;
3333
import org.junit.Before;
34-
import org.junit.Rule;
3534
import org.junit.Test;
3635
import org.junit.runner.RunWith;
3736
import org.junit.runners.JUnit4;
38-
import org.mockito.Mock;
3937
import org.mockito.Mockito;
40-
import org.mockito.junit.MockitoJUnit;
41-
import org.mockito.junit.MockitoRule;
4238
import org.mockito.stubbing.Answer;
4339

4440
@RunWith(JUnit4.class)
4541
public class BigtableTableAdminClientV2Test {
46-
@Rule public final MockitoRule mockitoRule = MockitoJUnit.rule();
4742

4843
private static final String TABLE_NAME =
4944
"projects/my-project/instances/my-instance/tables/my-table";
5045

5146
private GrpcBigtableTableAdminStub mockStub;
5247

53-
@Mock private AwaitConsistencyCallableV2 mockAwaitConsistencyCallable;
48+
private AwaitConsistencyCallableV2 mockAwaitConsistencyCallable;
5449

55-
@Mock
5650
private OperationCallable<Void, Empty, OptimizeRestoredTableMetadata>
5751
mockOptimizeRestoredTableCallable;
5852

@@ -62,6 +56,10 @@ public class BigtableTableAdminClientV2Test {
6256
public void setUp() {
6357
mockStub =
6458
Mockito.mock(GrpcBigtableTableAdminStub.class, Mockito.withSettings().withoutAnnotations());
59+
mockAwaitConsistencyCallable =
60+
Mockito.mock(AwaitConsistencyCallableV2.class, Mockito.withSettings().withoutAnnotations());
61+
mockOptimizeRestoredTableCallable =
62+
Mockito.mock(OperationCallable.class, Mockito.withSettings().withoutAnnotations());
6563
client =
6664
new BigtableTableAdminClientV2(
6765
mockStub, null, false, mockAwaitConsistencyCallable, mockOptimizeRestoredTableCallable);

java-pubsub/google-cloud-pubsub/src/test/java/com/google/cloud/pubsub/v1/StreamingSubscriberConnectionTest.java

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,10 @@ public void setUp() {
103103
systemExecutor = new FakeScheduledExecutorService();
104104
executor = new FakeScheduledExecutorService();
105105
clock = systemExecutor.getClock();
106-
mockSubscriberStub = mock(SubscriberStub.class, RETURNS_DEEP_STUBS);
106+
mockSubscriberStub =
107+
mock(
108+
SubscriberStub.class,
109+
withSettings().withoutAnnotations().defaultAnswer(RETURNS_DEEP_STUBS));
107110
}
108111

109112
@After
@@ -128,7 +131,8 @@ public void testRunShutdown_TimeoutMet() throws Exception {
128131
SubscriberShutdownSettings shutdownSettings =
129132
SubscriberShutdownSettings.newBuilder().setTimeout(Duration.ofSeconds(10)).build();
130133
StreamingSubscriberConnection.Builder builder =
131-
StreamingSubscriberConnection.newBuilder(mock(MessageReceiverWithAckResponse.class));
134+
StreamingSubscriberConnection.newBuilder(
135+
mock(MessageReceiverWithAckResponse.class, withSettings().withoutAnnotations()));
132136
builder.setSubscriberShutdownSettings(shutdownSettings);
133137
StreamingSubscriberConnection streamingSubscriberConnection =
134138
getStreamingSubscriberConnectionFromBuilder(builder);
@@ -149,7 +153,8 @@ public void testRunShutdown_TimeoutExceeded() throws Exception {
149153
SubscriberShutdownSettings shutdownSettings =
150154
SubscriberShutdownSettings.newBuilder().setTimeout(Duration.ofSeconds(2)).build();
151155
StreamingSubscriberConnection.Builder builder =
152-
StreamingSubscriberConnection.newBuilder(mock(MessageReceiverWithAckResponse.class));
156+
StreamingSubscriberConnection.newBuilder(
157+
mock(MessageReceiverWithAckResponse.class, withSettings().withoutAnnotations()));
153158
StreamingSubscriberConnection streamingSubscriberConnection =
154159
getStreamingSubscriberConnectionFromBuilder(builder, shutdownSettings);
155160
streamingSubscriberConnection.setExactlyOnceDeliveryEnabled(true);
@@ -199,11 +204,13 @@ public void testAckDuringNackImmediatelyShutdown() throws Exception {
199204
.setMode(SubscriberShutdownSettings.ShutdownMode.NACK_IMMEDIATELY)
200205
.build();
201206

202-
MessageDispatcher mockMessageDispatcher = mock(MessageDispatcher.class);
207+
MessageDispatcher mockMessageDispatcher =
208+
mock(MessageDispatcher.class, withSettings().withoutAnnotations());
203209
when(mockMessageDispatcher.getNackImmediatelyShutdownInProgress()).thenReturn(true);
204210

205211
StreamingSubscriberConnection.Builder builder =
206-
StreamingSubscriberConnection.newBuilder(mock(MessageReceiverWithAckResponse.class));
212+
StreamingSubscriberConnection.newBuilder(
213+
mock(MessageReceiverWithAckResponse.class, withSettings().withoutAnnotations()));
207214
StreamingSubscriberConnection streamingSubscriberConnection =
208215
getStreamingSubscriberConnectionFromBuilder(builder, shutdownSettings);
209216

@@ -687,8 +694,9 @@ public void testMaxPerRequestChanges() {
687694
@Test
688695
public void testClientPinger_pingSent() {
689696
BidiStreamingCallable<StreamingPullRequest, StreamingPullResponse> mockStreamingCallable =
690-
mock(BidiStreamingCallable.class);
691-
ClientStream<StreamingPullRequest> mockClientStream = mock(ClientStream.class);
697+
mock(BidiStreamingCallable.class, withSettings().withoutAnnotations());
698+
ClientStream<StreamingPullRequest> mockClientStream =
699+
mock(ClientStream.class, withSettings().withoutAnnotations());
692700
when(mockSubscriberStub.streamingPullCallable()).thenReturn(mockStreamingCallable);
693701
when(mockStreamingCallable.splitCall(any(ResponseObserver.class), any()))
694702
.thenReturn(mockClientStream);
@@ -730,8 +738,9 @@ public void testClientPinger_pingSent() {
730738
@Test
731739
public void testClientPinger_pingsNotSentWhenDisabled() {
732740
BidiStreamingCallable<StreamingPullRequest, StreamingPullResponse> mockStreamingCallable =
733-
mock(BidiStreamingCallable.class);
734-
ClientStream<StreamingPullRequest> mockClientStream = mock(ClientStream.class);
741+
mock(BidiStreamingCallable.class, withSettings().withoutAnnotations());
742+
ClientStream<StreamingPullRequest> mockClientStream =
743+
mock(ClientStream.class, withSettings().withoutAnnotations());
735744
when(mockSubscriberStub.streamingPullCallable()).thenReturn(mockStreamingCallable);
736745
when(mockStreamingCallable.splitCall(any(ResponseObserver.class), any()))
737746
.thenReturn(mockClientStream);
@@ -755,8 +764,9 @@ public void testClientPinger_pingsNotSentWhenDisabled() {
755764
@Test
756765
public void testServerMonitor_timesOut() {
757766
BidiStreamingCallable<StreamingPullRequest, StreamingPullResponse> mockStreamingCallable =
758-
mock(BidiStreamingCallable.class);
759-
ClientStream<StreamingPullRequest> mockClientStream = mock(ClientStream.class);
767+
mock(BidiStreamingCallable.class, withSettings().withoutAnnotations());
768+
ClientStream<StreamingPullRequest> mockClientStream =
769+
mock(ClientStream.class, withSettings().withoutAnnotations());
760770
ArgumentCaptor<ResponseObserver<StreamingPullResponse>> observerCaptor =
761771
ArgumentCaptor.forClass(ResponseObserver.class);
762772
when(mockSubscriberStub.streamingPullCallable()).thenReturn(mockStreamingCallable);
@@ -786,7 +796,8 @@ public void testServerMonitor_timesOut() {
786796
streamingSubscriberConnection.awaitRunning();
787797

788798
ResponseObserver<StreamingPullResponse> observer = observerCaptor.getValue();
789-
StreamController mockController = mock(StreamController.class);
799+
StreamController mockController =
800+
mock(StreamController.class, withSettings().withoutAnnotations());
790801
observer.onStart(mockController);
791802

792803
systemExecutor.advanceTime(CLIENT_PING_INTERVAL);
@@ -803,8 +814,9 @@ public void testServerMonitor_timesOut() {
803814
@Test
804815
public void testServerMonitor_doesNotTimeOutIfResponseReceived() {
805816
BidiStreamingCallable<StreamingPullRequest, StreamingPullResponse> mockStreamingCallable =
806-
mock(BidiStreamingCallable.class);
807-
ClientStream<StreamingPullRequest> mockClientStream = mock(ClientStream.class);
817+
mock(BidiStreamingCallable.class, withSettings().withoutAnnotations());
818+
ClientStream<StreamingPullRequest> mockClientStream =
819+
mock(ClientStream.class, withSettings().withoutAnnotations());
808820
ArgumentCaptor<ResponseObserver<StreamingPullResponse>> observerCaptor =
809821
ArgumentCaptor.forClass(ResponseObserver.class);
810822
when(mockSubscriberStub.streamingPullCallable()).thenReturn(mockStreamingCallable);
@@ -818,7 +830,8 @@ public void testServerMonitor_doesNotTimeOutIfResponseReceived() {
818830
streamingSubscriberConnection.awaitRunning();
819831

820832
ResponseObserver<StreamingPullResponse> observer = observerCaptor.getValue();
821-
StreamController mockController = mock(StreamController.class);
833+
StreamController mockController =
834+
mock(StreamController.class, withSettings().withoutAnnotations());
822835
observer.onStart(mockController);
823836

824837
// t=30s: ping sent.
@@ -837,7 +850,8 @@ private StreamingSubscriberConnection getStreamingSubscriberConnection(
837850
boolean exactlyOnceDeliveryEnabled) {
838851
StreamingSubscriberConnection streamingSubscriberConnection =
839852
getStreamingSubscriberConnectionFromBuilder(
840-
StreamingSubscriberConnection.newBuilder(mock(MessageReceiverWithAckResponse.class)));
853+
StreamingSubscriberConnection.newBuilder(
854+
mock(MessageReceiverWithAckResponse.class, withSettings().withoutAnnotations())));
841855

842856
// This would normally be set from the streaming pull response
843857
streamingSubscriberConnection.setExactlyOnceDeliveryEnabled(exactlyOnceDeliveryEnabled);
@@ -848,7 +862,8 @@ private StreamingSubscriberConnection getStreamingSubscriberConnection(
848862
private StreamingSubscriberConnection getKeepaliveStreamingSubscriberConnection() {
849863
StreamingSubscriberConnection streamingSubscriberConnection =
850864
getStreamingSubscriberConnectionFromBuilder(
851-
StreamingSubscriberConnection.newBuilder(mock(MessageReceiverWithAckResponse.class))
865+
StreamingSubscriberConnection.newBuilder(
866+
mock(MessageReceiverWithAckResponse.class, withSettings().withoutAnnotations()))
852867
.setProtocolVersion(KEEP_ALIVE_SUPPORT_VERSION));
853868

854869
return streamingSubscriberConnection;
@@ -860,11 +875,12 @@ private StreamingSubscriberConnection getStreamingSubscriberConnectionFromBuilde
860875
.setSubscription(MOCK_SUBSCRIPTION_NAME)
861876
.setAckExpirationPadding(ACK_EXPIRATION_PADDING_DEFAULT_DURATION)
862877
.setMaxAckExtensionPeriod(MAX_ACK_EXTENSION_PERIOD)
863-
.setAckLatencyDistribution(mock(Distribution.class))
878+
.setAckLatencyDistribution(mock(Distribution.class, withSettings().withoutAnnotations()))
864879
.setSubscriberStub(mockSubscriberStub)
865880
.setChannelAffinity(0)
866-
.setFlowControlSettings(mock(FlowControlSettings.class))
867-
.setFlowController(mock(FlowController.class))
881+
.setFlowControlSettings(
882+
mock(FlowControlSettings.class, withSettings().withoutAnnotations()))
883+
.setFlowController(mock(FlowController.class, withSettings().withoutAnnotations()))
868884
.setExecutor(executor)
869885
.setSystemExecutor(systemExecutor)
870886
.setClock(clock)
@@ -881,11 +897,12 @@ private StreamingSubscriberConnection getStreamingSubscriberConnectionFromBuilde
881897
return builder
882898
.setSubscription(MOCK_SUBSCRIPTION_NAME)
883899
.setAckExpirationPadding(ACK_EXPIRATION_PADDING_DEFAULT_DURATION)
884-
.setAckLatencyDistribution(mock(Distribution.class))
900+
.setAckLatencyDistribution(mock(Distribution.class, withSettings().withoutAnnotations()))
885901
.setSubscriberStub(mockSubscriberStub)
886902
.setChannelAffinity(0)
887-
.setFlowControlSettings(mock(FlowControlSettings.class))
888-
.setFlowController(mock(FlowController.class))
903+
.setFlowControlSettings(
904+
mock(FlowControlSettings.class, withSettings().withoutAnnotations()))
905+
.setFlowController(mock(FlowController.class, withSettings().withoutAnnotations()))
889906
.setExecutor(executor)
890907
.setSystemExecutor(systemExecutor)
891908
.setClock(clock)

java-spanner/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerCloudMonitoringExporterTest.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,9 @@
7272
import java.util.stream.Collectors;
7373
import org.junit.After;
7474
import org.junit.Before;
75-
import org.junit.Rule;
7675
import org.junit.Test;
7776
import org.mockito.ArgumentCaptor;
78-
import org.mockito.Mock;
7977
import org.mockito.Mockito;
80-
import org.mockito.junit.MockitoJUnit;
81-
import org.mockito.junit.MockitoRule;
8278

8379
public class SpannerCloudMonitoringExporterTest {
8480

@@ -91,9 +87,7 @@ public class SpannerCloudMonitoringExporterTest {
9187
private static final String clientHash = "spanner-test";
9288
private static final String instanceConfigId = "fake-instance-config-id";
9389

94-
@Rule public final MockitoRule mockitoRule = MockitoJUnit.rule();
95-
96-
@Mock private MetricServiceStub mockMetricServiceStub;
90+
private MetricServiceStub mockMetricServiceStub;
9791
private MetricServiceClient fakeMetricServiceClient;
9892
private SpannerCloudMonitoringExporter exporter;
9993

@@ -107,6 +101,8 @@ public class SpannerCloudMonitoringExporterTest {
107101

108102
@Before
109103
public void setUp() {
104+
mockMetricServiceStub =
105+
Mockito.mock(MetricServiceStub.class, Mockito.withSettings().withoutAnnotations());
110106
fakeMetricServiceClient = new FakeMetricServiceClient(mockMetricServiceStub);
111107
exporter = new SpannerCloudMonitoringExporter(fakeMetricServiceClient);
112108

java-spanner/google-cloud-spanner/src/test/java/com/google/cloud/spanner/SpannerImplTest.java

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@
6262
public class SpannerImplTest {
6363
@Mock private SpannerRpc rpc;
6464
@Mock private SpannerOptions spannerOptions;
65-
@Mock private DatabaseAdminStubSettings databaseAdminStubSettings;
66-
@Mock private DatabaseAdminStub databaseAdminStub;
67-
@Mock private InstanceAdminStubSettings instanceAdminStubSettings;
68-
@Mock private InstanceAdminStub instanceAdminStub;
65+
private DatabaseAdminStubSettings databaseAdminStubSettings;
66+
private DatabaseAdminStub databaseAdminStub;
67+
private InstanceAdminStubSettings instanceAdminStubSettings;
68+
private InstanceAdminStub instanceAdminStub;
6969
private SpannerImpl impl;
7070

7171
@Captor ArgumentCaptor<Map<SpannerRpc.Option, Object>> options;
@@ -78,6 +78,15 @@ public static void setupOpenTelemetry() {
7878

7979
@Before
8080
public void setUp() {
81+
databaseAdminStubSettings =
82+
Mockito.mock(DatabaseAdminStubSettings.class, Mockito.withSettings().withoutAnnotations());
83+
databaseAdminStub =
84+
Mockito.mock(DatabaseAdminStub.class, Mockito.withSettings().withoutAnnotations());
85+
instanceAdminStubSettings =
86+
Mockito.mock(InstanceAdminStubSettings.class, Mockito.withSettings().withoutAnnotations());
87+
instanceAdminStub =
88+
Mockito.mock(InstanceAdminStub.class, Mockito.withSettings().withoutAnnotations());
89+
8190
MockitoAnnotations.initMocks(this);
8291
when(spannerOptions.getNumChannels()).thenReturn(4);
8392
when(spannerOptions.getDatabaseRole()).thenReturn("role");

sdk-platform-java/gax-java/gax-grpc/src/test/java/com/google/api/gax/grpc/GrpcLongRunningClientTest.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,8 @@ class GrpcLongRunningClientTest {
5050

5151
@Test
5252
void get() {
53-
OperationsStub operationsStub = mock(OperationsStub.class);
53+
OperationsStub operationsStub =
54+
mock(OperationsStub.class, org.mockito.Mockito.withSettings().withoutAnnotations());
5455
when(operationsStub.getOperationCallable())
5556
.thenReturn(
5657
new UnaryCallable<GetOperationRequest, Operation>() {
@@ -73,7 +74,8 @@ public ApiFuture<Operation> futureCall(
7374

7475
@Test
7576
void cancel() {
76-
OperationsStub operationsStub = mock(OperationsStub.class);
77+
OperationsStub operationsStub =
78+
mock(OperationsStub.class, org.mockito.Mockito.withSettings().withoutAnnotations());
7779
when(operationsStub.cancelOperationCallable())
7880
.thenReturn(
7981
new UnaryCallable<CancelOperationRequest, Empty>() {
@@ -94,7 +96,8 @@ public ApiFuture<Empty> futureCall(
9496

9597
@Test
9698
void delete() {
97-
OperationsStub operationsStub = mock(OperationsStub.class);
99+
OperationsStub operationsStub =
100+
mock(OperationsStub.class, org.mockito.Mockito.withSettings().withoutAnnotations());
98101
when(operationsStub.deleteOperationCallable())
99102
.thenReturn(
100103
new UnaryCallable<DeleteOperationRequest, Empty>() {

0 commit comments

Comments
 (0)