Skip to content

Commit 50e75bf

Browse files
author
Simon Stone
committed
[FAB-16655] Warnings as errors for Java chaincode
Enable warnings as errors using -Werror, enable all linting checks with -Xlint:all,-try, and fix all the resulting errors. The -try part is needed to disable an error on the iterators, which cannot be fixed. It basically says "you're implementing AutoCloseable, don't you dare throw InterruptedException!" - which we don't. Signed-off-by: Simon Stone <[email protected]> Change-Id: Id1b34b4683fa66039c09905fd3607baeb4292f20
1 parent d79f5a6 commit 50e75bf

File tree

14 files changed

+49
-56
lines changed

14 files changed

+49
-56
lines changed

build.gradle

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,10 @@ subprojects {
3939
testCompile 'com.github.stefanbirkner:system-rules:1.17.0'
4040
}
4141

42-
tasks.withType(JavaCompile) {
43-
options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation"
42+
if (!it.name.equals('fabric-chaincode-protos')) {
43+
tasks.withType(JavaCompile) {
44+
options.compilerArgs << "-Xlint:all,-try" << "-Werror"
45+
}
4446
}
4547

4648
}

fabric-chaincode-example-maven/src/main/java/org/hyperledger/fabric/example/SimpleChaincode.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ private Response invoke(ChaincodeStub stub, List<String> args) {
100100

101101
_logger.info("Transfer complete");
102102

103-
return newSuccessResponse("invoke finished successfully", ByteString.copyFrom(accountFromKey + ": " + accountFromValue + " " + accountToKey + ": " + accountToValue, UTF_8).toByteArray());
103+
return newSuccessResponse(null, ByteString.copyFrom(accountFromKey + ": " + accountFromValue + " " + accountToKey + ": " + accountToValue, UTF_8).toByteArray());
104104
}
105105

106106
// Deletes an entity from state
@@ -126,7 +126,7 @@ private Response query(ChaincodeStub stub, List<String> args) {
126126
return newErrorResponse(String.format("Error: state for %s is null", key));
127127
}
128128
_logger.info(String.format("Query Response:\nName: %s, Amount: %s\n", key, val));
129-
return newSuccessResponse(val, ByteString.copyFrom(val, UTF_8).toByteArray());
129+
return newSuccessResponse(null, ByteString.copyFrom(val, UTF_8).toByteArray());
130130
}
131131

132132
public static void main(String[] args) {

fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/FirstNetworkIntegrationTest.java

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@
4747
public class FirstNetworkIntegrationTest {
4848

4949
@ClassRule
50-
public static DockerComposeContainer env = new DockerComposeContainer(
50+
public static DockerComposeContainer<?> env = new DockerComposeContainer<>(
5151
new File("src/test/resources/first-network/docker-compose-cli.yaml")
5252
)
5353
.withLocalCompose(false)
@@ -224,11 +224,11 @@ private void testSACCChaincodeInstallInstantiateInvokeQuery(HFClient client, Ins
224224

225225
// Creating proposal for query
226226
final TransactionProposalRequest queryAProposalRequest = generateSACCQueryRequest(client, installProposalRequest.getChaincodeName(), "a");
227-
Utils.sendTransactionProposalQuery(queryAProposalRequest, myChannel, peer1org1, Matchers.is(200), Matchers.anything(), Matchers.is(ByteString.copyFromUtf8("100")));
227+
Utils.sendTransactionProposalQuery(queryAProposalRequest, myChannel, peer1org1, Matchers.is(200), Matchers.isEmptyString(), Matchers.is(ByteString.copyFromUtf8("100")));
228228

229229
// Creating proposal for query
230230
final TransactionProposalRequest queryBProposalRequest = generateSACCQueryRequest(client, installProposalRequest.getChaincodeName(), "b");
231-
Utils.sendTransactionProposalQuery(queryBProposalRequest, myChannel, org1peers, Matchers.is(200), Matchers.anything(), Matchers.is(ByteString.copyFromUtf8("200")));
231+
Utils.sendTransactionProposalQuery(queryBProposalRequest, myChannel, org1peers, Matchers.is(200), Matchers.isEmptyString(), Matchers.is(ByteString.copyFromUtf8("200")));
232232

233233
}
234234

@@ -276,60 +276,60 @@ void RunSBE(HFClient client, Channel channel, String mode) throws NoSuchAlgorit
276276
Utils.sendTransactionProposalInvoke(proposal, channel, peer0org1, channel.getOrderers());
277277

278278
proposal = generateSBECCTransactionRequest(client, "getval", mode);
279-
Utils.sendTransactionProposalQuery(proposal, channel, peer0org1, Matchers.is(200), Matchers.anything(), Matchers.is(ByteString.copyFrom("foo", StandardCharsets.UTF_8)));
279+
Utils.sendTransactionProposalQuery(proposal, channel, peer0org1, Matchers.is(200), Matchers.isEmptyString(), Matchers.is(ByteString.copyFrom("foo", StandardCharsets.UTF_8)));
280280

281281
proposal = generateSBECCTransactionRequest(client, "addorgs", mode, "Org1MSP");
282282
Utils.sendTransactionProposalInvoke(proposal, channel, peer0org1, channel.getOrderers());
283283

284284
proposal = generateSBECCTransactionRequest(client, "listorgs", mode);
285-
Utils.sendTransactionProposalQuery(proposal, channel, peer0org1, Matchers.is(200), Matchers.anything(), Matchers.is(ByteString.copyFrom("[\"Org1MSP\"]", StandardCharsets.UTF_8)));
285+
Utils.sendTransactionProposalQuery(proposal, channel, peer0org1, Matchers.is(200), Matchers.isEmptyString(), Matchers.is(ByteString.copyFrom("[\"Org1MSP\"]", StandardCharsets.UTF_8)));
286286

287287
proposal = generateSBECCTransactionRequest(client, "setval", mode, "val1");
288288
Utils.sendTransactionProposalInvoke(proposal, channel, peer0org1, channel.getOrderers());
289289

290290
proposal = generateSBECCTransactionRequest(client, "getval", mode);
291-
Utils.sendTransactionProposalQuery(proposal, channel, peer0org1, Matchers.is(200), Matchers.anything(), Matchers.is(ByteString.copyFrom("val1", StandardCharsets.UTF_8)));
291+
Utils.sendTransactionProposalQuery(proposal, channel, peer0org1, Matchers.is(200), Matchers.isEmptyString(), Matchers.is(ByteString.copyFrom("val1", StandardCharsets.UTF_8)));
292292

293293
client.setUserContext(Utils.getUser1Org2TLS());
294294
proposal = generateSBECCTransactionRequest(client, "setval", mode, "val2");
295295
Utils.sendTransactionProposalInvoke(proposal, channel, peer0org2, channel.getOrderers(), true);
296296

297297
proposal = generateSBECCTransactionRequest(client, "getval", mode);
298-
Utils.sendTransactionProposalQuery(proposal, channel, peer0org2, Matchers.is(200), Matchers.anything(), Matchers.is(ByteString.copyFrom("val1", StandardCharsets.UTF_8)));
298+
Utils.sendTransactionProposalQuery(proposal, channel, peer0org2, Matchers.is(200), Matchers.isEmptyString(), Matchers.is(ByteString.copyFrom("val1", StandardCharsets.UTF_8)));
299299

300300
client.setUserContext(Utils.getUser1Org1TLS());
301301
proposal = generateSBECCTransactionRequest(client, "addorgs", mode, "Org2MSP");
302302
Utils.sendTransactionProposalInvoke(proposal, channel, peer0org1, channel.getOrderers());
303303

304304
proposal = generateSBECCTransactionRequest(client, "listorgs", mode);
305-
Utils.sendTransactionProposalQuery(proposal, channel, peer0org1, Matchers.is(200), Matchers.anything(), Matchers.anyOf(Matchers.is(ByteString.copyFrom("[\"Org1MSP\",\"Org2MSP\"]", StandardCharsets.UTF_8)),Matchers.is(ByteString.copyFrom("[\"Org2MSP\",\"Org1MSP\"]", StandardCharsets.UTF_8))));
305+
Utils.sendTransactionProposalQuery(proposal, channel, peer0org1, Matchers.is(200), Matchers.isEmptyString(), Matchers.anyOf(Matchers.is(ByteString.copyFrom("[\"Org1MSP\",\"Org2MSP\"]", StandardCharsets.UTF_8)),Matchers.is(ByteString.copyFrom("[\"Org2MSP\",\"Org1MSP\"]", StandardCharsets.UTF_8))));
306306

307307
client.setUserContext(Utils.getUser1Org2TLS());
308308
proposal = generateSBECCTransactionRequest(client, "setval", mode, "val3");
309309
Utils.sendTransactionProposalInvoke(proposal, channel, peer0org2, channel.getOrderers(), true);
310310

311311
proposal = generateSBECCTransactionRequest(client, "getval", mode);
312-
Utils.sendTransactionProposalQuery(proposal, channel, peer0org2, Matchers.is(200), Matchers.anything(), Matchers.is(ByteString.copyFrom("val1", StandardCharsets.UTF_8)));
312+
Utils.sendTransactionProposalQuery(proposal, channel, peer0org2, Matchers.is(200), Matchers.isEmptyString(), Matchers.is(ByteString.copyFrom("val1", StandardCharsets.UTF_8)));
313313

314314
proposal = generateSBECCTransactionRequest(client, "setval", mode, "val4");
315315
Utils.sendTransactionProposalInvoke(proposal, channel, allpeers0, channel.getOrderers());
316316

317317
client.setUserContext(Utils.getUser1Org1TLS());
318318
proposal = generateSBECCTransactionRequest(client, "getval", mode);
319-
Utils.sendTransactionProposalQuery(proposal, channel, peer0org1, Matchers.is(200), Matchers.anything(), Matchers.is(ByteString.copyFrom("val4", StandardCharsets.UTF_8)));
319+
Utils.sendTransactionProposalQuery(proposal, channel, peer0org1, Matchers.is(200), Matchers.isEmptyString(), Matchers.is(ByteString.copyFrom("val4", StandardCharsets.UTF_8)));
320320

321321
client.setUserContext(Utils.getUser1Org2TLS());
322322
proposal = generateSBECCTransactionRequest(client, "delorgs", mode, "Org1MSP");
323323
Utils.sendTransactionProposalInvoke(proposal, channel, peer0org2, channel.getOrderers(), true);
324324

325325
proposal = generateSBECCTransactionRequest(client, "listorgs", mode);
326-
Utils.sendTransactionProposalQuery(proposal, channel, peer0org2, Matchers.is(200), Matchers.anything(), Matchers.anyOf(Matchers.is(ByteString.copyFrom("[\"Org1MSP\",\"Org2MSP\"]", StandardCharsets.UTF_8)),Matchers.is(ByteString.copyFrom("[\"Org2MSP\",\"Org1MSP\"]", StandardCharsets.UTF_8))));
326+
Utils.sendTransactionProposalQuery(proposal, channel, peer0org2, Matchers.is(200), Matchers.isEmptyString(), Matchers.anyOf(Matchers.is(ByteString.copyFrom("[\"Org1MSP\",\"Org2MSP\"]", StandardCharsets.UTF_8)),Matchers.is(ByteString.copyFrom("[\"Org2MSP\",\"Org1MSP\"]", StandardCharsets.UTF_8))));
327327

328328
proposal = generateSBECCTransactionRequest(client, "delorgs", mode, "Org1MSP");
329329
Utils.sendTransactionProposalInvoke(proposal, channel, allpeers0, channel.getOrderers());
330330

331331
proposal = generateSBECCTransactionRequest(client, "listorgs", mode);
332-
Utils.sendTransactionProposalQuery(proposal, channel, peer0org2, Matchers.is(200), Matchers.anything(), Matchers.is(ByteString.copyFrom("[\"Org2MSP\"]", StandardCharsets.UTF_8)));
332+
Utils.sendTransactionProposalQuery(proposal, channel, peer0org2, Matchers.is(200), Matchers.isEmptyString(), Matchers.is(ByteString.copyFrom("[\"Org2MSP\"]", StandardCharsets.UTF_8)));
333333

334334
}
335335

@@ -383,7 +383,7 @@ private void executeAndValidateQueryOnAccount(HFClient client, Channel channel,
383383
.filter(peer -> peer.getName().contains(peerName))
384384
.collect(Collectors.toList()),
385385
Matchers.is(ChaincodeResponse.Status.SUCCESS.getStatus()),
386-
Matchers.anything(),
386+
Matchers.isEmptyString(),
387387
Matchers.is(ByteString.copyFrom(expectedAmount, StandardCharsets.UTF_8))
388388
);
389389
}
@@ -439,7 +439,7 @@ private void executeAndValidateQueryOnAccountNewPM(HFClient client, Channel chan
439439
.filter(peer -> peer.getName().contains(peerName))
440440
.collect(Collectors.toList()),
441441
Matchers.is(ChaincodeResponse.Status.SUCCESS.getStatus()),
442-
Matchers.anything(),
442+
Matchers.isEmptyString(),
443443
Matchers.is(ByteString.copyFrom(expectedAmount, StandardCharsets.UTF_8))
444444
);
445445
}

fabric-chaincode-integration-test/src/test/java/org/hyperleder/fabric/shim/integration/Utils.java

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242

4343
import com.github.dockerjava.api.model.Container;
4444
import com.github.dockerjava.api.model.Image;
45+
import com.google.protobuf.ByteString;
4546

4647
import org.apache.commons.compress.archivers.ArchiveEntry;
4748
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
@@ -175,14 +176,11 @@ public static InputStream generateTarGzInputStream(File src, String pathPrefix)
175176

176177
String sourcePath = sourceDirectory.getAbsolutePath();
177178

178-
TarArchiveOutputStream archiveOutputStream = new TarArchiveOutputStream(new GzipCompressorOutputStream(new BufferedOutputStream(bos)));
179-
archiveOutputStream.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
180-
181-
try {
179+
try (TarArchiveOutputStream archiveOutputStream = new TarArchiveOutputStream(new GzipCompressorOutputStream(new BufferedOutputStream(bos)))) {
180+
archiveOutputStream.setLongFileMode(TarArchiveOutputStream.LONGFILE_GNU);
182181
Collection<File> childrenFiles = org.apache.commons.io.FileUtils.listFiles(sourceDirectory, null, true);
183182

184183
ArchiveEntry archiveEntry;
185-
FileInputStream fileInputStream;
186184
for (File childFile : childrenFiles) {
187185
String childPath = childFile.getAbsolutePath();
188186
String relativePath = childPath.substring((sourcePath.length() + 1), childPath.length());
@@ -194,18 +192,12 @@ public static InputStream generateTarGzInputStream(File src, String pathPrefix)
194192
relativePath = FilenameUtils.separatorsToUnix(relativePath);
195193

196194
archiveEntry = new TarArchiveEntry(childFile, relativePath);
197-
fileInputStream = new FileInputStream(childFile);
198-
archiveOutputStream.putArchiveEntry(archiveEntry);
199-
200-
try {
195+
try (FileInputStream fileInputStream = new FileInputStream(childFile)) {
196+
archiveOutputStream.putArchiveEntry(archiveEntry);
201197
IOUtils.copy(fileInputStream, archiveOutputStream);
202-
} finally {
203-
IOUtils.closeQuietly(fileInputStream);
204198
archiveOutputStream.closeArchiveEntry();
205199
}
206200
}
207-
} finally {
208-
IOUtils.closeQuietly(archiveOutputStream);
209201
}
210202

211203
return new ByteArrayInputStream(bos.toByteArray());
@@ -473,7 +465,7 @@ static public void sendTransactionProposalInvoke(TransactionProposalRequest prop
473465
}
474466
}
475467

476-
static public void sendTransactionProposalQuery(TransactionProposalRequest proposal, Channel channel, Collection<Peer> peers, Matcher statusMatcher, Matcher messageMatcher, Matcher payloadMatcher) throws InvalidArgumentException, ProposalException {
468+
static public void sendTransactionProposalQuery(TransactionProposalRequest proposal, Channel channel, Collection<Peer> peers, Matcher<Integer> statusMatcher, Matcher<String> messageMatcher, Matcher<ByteString> payloadMatcher) throws InvalidArgumentException, ProposalException {
477469
// Send proposal and wait for responses
478470
System.out.println("Sending proposal for " + proposal.getFcn() + "(" + String.join(", ", proposal.getArgs()) + ") to peers: " + String.join(", ", peers.stream().map(p -> p.getName()).collect(Collectors.toList())));
479471
final Collection<ProposalResponse> queryAResponses = channel.sendTransactionProposal(proposal, peers);

fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/JSONTransactionSerializer.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
import java.lang.reflect.Array;
1212
import java.lang.reflect.Field;
13+
import java.lang.reflect.InvocationTargetException;
1314
import java.nio.charset.StandardCharsets;
1415
import java.util.Iterator;
1516
import java.util.Map;
@@ -154,8 +155,8 @@ Object createComponentInstance(String format, String jsonString, TypeSchema ts)
154155
DataTypeDefinition dtd = this.typeRegistry.getDataType(format);
155156
Object obj;
156157
try {
157-
obj = dtd.getTypeClass().newInstance();
158-
} catch (InstantiationException | IllegalAccessException e1) {
158+
obj = dtd.getTypeClass().getDeclaredConstructor().newInstance();
159+
} catch (IllegalAccessException | InstantiationException | InvocationTargetException | NoSuchMethodException e1) {
159160
throw new ContractRuntimeException("Unable to to create new instance of type", e1);
160161
}
161162

fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/execution/impl/ContractExecutionService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ public Chaincode.Response executeRequest(TxFunction txFn, InvocationRequest req,
6363
response = ResponseUtils.newSuccessResponse(convertReturn(value, txFn));
6464
}
6565

66-
} catch (IllegalAccessException | InstantiationException e) {
66+
} catch (IllegalAccessException | InstantiationException | NoSuchMethodException e) {
6767
String message = String.format("Could not execute contract method: %s", rd.toString());
6868
throw new ContractRuntimeException(message, e);
6969
} catch (InvocationTargetException e) {

fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/TxFunction.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
package org.hyperledger.fabric.contract.routing;
77

8+
import java.lang.reflect.InvocationTargetException;
89
import java.lang.reflect.Method;
910
import java.util.List;
1011

@@ -19,7 +20,7 @@ interface Routing {
1920

2021
Class<? extends ContractInterface> getContractClass();
2122

22-
ContractInterface getContractInstance() throws InstantiationException, IllegalAccessException;
23+
ContractInterface getContractInstance() throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException;
2324

2425
}
2526

fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/RoutingRegistryImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ public Collection<ContractDefinition> getAllDefinitions() {
141141
* org.hyperledger.fabric.contract.routing.RoutingRegistry#findAndSetContracts()
142142
*/
143143
@Override
144+
@SuppressWarnings("unchecked")
144145
public void findAndSetContracts(TypeRegistry typeRegistry) {
145146

146147
// Find all classes that are valid contract or data type instances.
@@ -197,7 +198,7 @@ public void findAndSetContracts(TypeRegistry typeRegistry) {
197198
for (Class<ContractInterface> contractClass : contractClasses) {
198199
String className = contractClass.getCanonicalName();
199200
if (!seenClass.contains(className)) {
200-
ContractDefinition contract = addNewContract((Class<ContractInterface>) contractClass);
201+
ContractDefinition contract = addNewContract(contractClass);
201202

202203
logger.debug("Searching annotated methods");
203204
for (Method m : contractClass.getMethods()) {

fabric-chaincode-shim/src/main/java/org/hyperledger/fabric/contract/routing/impl/TxFunctionImpl.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66
package org.hyperledger.fabric.contract.routing.impl;
77

8+
import java.lang.reflect.InvocationTargetException;
89
import java.lang.reflect.Method;
910
import java.util.ArrayList;
1011
import java.util.Arrays;
@@ -54,10 +55,8 @@ public Class<? extends ContractInterface> getContractClass() {
5455
}
5556

5657
@Override
57-
public ContractInterface getContractInstance() throws InstantiationException, IllegalAccessException {
58-
59-
return clazz.newInstance();
60-
58+
public ContractInterface getContractInstance() throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
59+
return clazz.getDeclaredConstructor().newInstance();
6160
}
6261

6362
@Override

fabric-chaincode-shim/src/test/java/org/hyperledger/fabric/contract/execution/ContractExecutionServiceTest.java

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import static org.mockito.Mockito.verify;
1515
import static org.mockito.Mockito.when;
1616

17+
import java.lang.reflect.InvocationTargetException;
1718
import java.util.ArrayList;
1819

1920
import org.hyperledger.fabric.contract.ChaincodeStubNaiveImpl;
@@ -36,10 +37,9 @@ public class ContractExecutionServiceTest {
3637
@Rule
3738
public ExpectedException thrown = ExpectedException.none();
3839

39-
@SuppressWarnings("rawtypes")
4040
@Test
4141
public void noReturnValue()
42-
throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException {
42+
throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException, SecurityException {
4343
TypeRegistry typeRegistry = new TypeRegistryImpl();
4444

4545
ContractExecutionService ces = new ContractExecutionService(typeRegistry);
@@ -52,20 +52,18 @@ public void noReturnValue()
5252
ChaincodeStub stub = new ChaincodeStubNaiveImpl();
5353

5454
when(txFn.getRouting()).thenReturn(routing);
55-
when(req.getArgs()).thenReturn(new ArrayList() {
56-
});
57-
when(routing.getMethod()).thenReturn(SampleContract.class.getMethod("noReturn", new Class[] { Context.class }));
55+
when(req.getArgs()).thenReturn(new ArrayList<byte[]>());
56+
when(routing.getMethod()).thenReturn(SampleContract.class.getMethod("noReturn", new Class<?>[] { Context.class }));
5857
when(routing.getContractInstance()).thenReturn(contract);
5958
ces.executeRequest(txFn, req, stub);
6059

6160
verify(contract).beforeTransaction(any());
6261

6362
}
6463

65-
@SuppressWarnings("rawtypes")
6664
@Test()
6765
public void failureToInvoke()
68-
throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException {
66+
throws IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException, SecurityException {
6967
TypeRegistry typeRegistry = new TypeRegistryImpl();
7068

7169
ContractExecutionService ces = new ContractExecutionService(typeRegistry);
@@ -78,8 +76,7 @@ public void failureToInvoke()
7876
ChaincodeStub stub = mock(ChaincodeStub.class);
7977

8078
when(txFn.getRouting()).thenReturn(routing);
81-
when(req.getArgs()).thenReturn(new ArrayList() {
82-
});
79+
when(req.getArgs()).thenReturn(new ArrayList<byte[]>());
8380

8481
when(routing.getContractInstance()).thenThrow(IllegalAccessException.class);
8582
when(routing.toString()).thenReturn("MockMethodName:MockClassName");

0 commit comments

Comments
 (0)