[
https://issues.apache.org/jira/browse/IGNITE-15256?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17393451#comment-17393451
]
Ivan Fedorenkov commented on IGNITE-15256:
------------------------------------------
Reproducer:
{code:java}
/**
* Test that client can invoke service method with externalizable parameter
after
* cluster failover.
*/
@Test
public void testServiceMethodInvocationAfterFailover() throws Exception {
PersonExternalizable person = new PersonExternalizable("Person 1");
ServiceConfiguration testServiceConfig = new ServiceConfiguration();
testServiceConfig.setName(SERVICE_NAME);
testServiceConfig.setService(new TestService());
testServiceConfig.setTotalCount(1);
Ignite ignite = null;
IgniteClient client = null;
try {
// Initialize cluster and client
ignite =
startGrid(getConfiguration().setServiceConfiguration(testServiceConfig));
client = startClient(ignite);
TestServiceInterface svc = client.services().serviceProxy(SERVICE_NAME,
TestServiceInterface.class);
// Invoke the service method with Externalizable parameter for the
first time.
// This triggers registration of the PersonExternalizable type in the
cluter.
String result = svc.testMethod(person);
assertEquals("testMethod(PersonExternalizable person): " + person,
result);
// Kill the cluster node, clean up the working directory (with cached
types)
// and drop the client connection.
ignite.close();
U.delete(U.resolveWorkDirectory(
U.defaultWorkDirectory(),
DataStorageConfiguration.DFLT_MARSHALLER_PATH,
false));
dropAllThinClientConnections();
// Invoke the service.
GridTestUtils.assertThrowsWithCause(() -> svc.testMethod(person),
ClientConnectionException.class);
// Restore the cluster and redeploy the service.
ignite =
startGrid(getConfiguration().setServiceConfiguration(testServiceConfig));
// Invoke the service method with Externalizable parameter once again.
// This should restore the client connection and trigger registration
of the
// PersonExternalizable once again.
result = svc.testMethod(person);
assertEquals("testMethod(PersonExternalizable person): " + person,
result);
} finally {
if (ignite != null) {
try {
ignite.close();
} catch (Throwable ignore) {
}
}
if (client != null) {
try {
client.close();
} catch (Throwable ignore) {
}
}
}
}
/** */
public static interface TestServiceInterface {
/** */
public String testMethod(PersonExternalizable person);
}
/**
* Implementation of TestServiceInterface.
*/
public static class TestService implements Service, TestServiceInterface {
/** {@inheritDoc} */
@Override public void cancel(ServiceContext ctx) {
// No-op.
}
/** {@inheritDoc} */
@Override public void init(ServiceContext ctx) throws Exception {
// No-op.
}
/** {@inheritDoc} */
@Override public void execute(ServiceContext ctx) throws Exception {
// No-op.
}
/** {@inheritDoc} */
@Override public String testMethod(PersonExternalizable person) {
return "testMethod(PersonExternalizable person): " + person;
}
} {code}
> ClassNotFoundException on attempt to invoke service method from Java
> ThinClient after cluster failover
> ------------------------------------------------------------------------------------------------------
>
> Key: IGNITE-15256
> URL: https://issues.apache.org/jira/browse/IGNITE-15256
> Project: Ignite
> Issue Type: Bug
> Components: thin client
> Affects Versions: 2.10
> Reporter: Ivan Fedorenkov
> Assignee: Ivan Fedorenkov
> Priority: Major
>
> Say, we have a thin client that uses some ignite service. This service
> exposes a method with an Externalizable input parameter. If cluster fails
> over after some period of successful interactions between the cluster and the
> client the following exception could be observed in cluster logs:
> {code:java}
> [2021-08-04
> 23:22:44,695][ERROR][client-connector-#114%client.ReliabilityTest%][ClientListenerNioListener]
> Failed to parse client request.
> class org.apache.ignite.binary.BinaryObjectException: Failed to unmarshal
> object with optimized marshaller
> at
> org.apache.ignite.internal.binary.BinaryUtils.doReadOptimized(BinaryUtils.java:1819)
> at
> org.apache.ignite.internal.binary.BinaryUtils.unmarshal(BinaryUtils.java:2034)
> at
> org.apache.ignite.internal.binary.BinaryReaderExImpl.readObjectDetached(BinaryReaderExImpl.java:1341)
> at
> org.apache.ignite.internal.binary.BinaryReaderExImpl.readObjectDetached(BinaryReaderExImpl.java:1336)
> at
> org.apache.ignite.internal.processors.platform.client.service.ClientServiceInvokeRequest.<init>(ClientServiceInvokeRequest.java:126)
> at
> org.apache.ignite.internal.processors.platform.client.ClientMessageParser.decode(ClientMessageParser.java:486)
> at
> org.apache.ignite.internal.processors.platform.client.ClientMessageParser.decode(ClientMessageParser.java:311)
> at
> org.apache.ignite.internal.processors.odbc.ClientListenerNioListener.onMessage(ClientListenerNioListener.java:164)
> at
> org.apache.ignite.internal.processors.odbc.ClientListenerNioListener.onMessage(ClientListenerNioListener.java:55)
> at
> org.apache.ignite.internal.util.nio.GridNioFilterChain$TailFilter.onMessageReceived(GridNioFilterChain.java:279)
> at
> org.apache.ignite.internal.util.nio.GridNioFilterAdapter.proceedMessageReceived(GridNioFilterAdapter.java:109)
> at
> org.apache.ignite.internal.util.nio.GridNioAsyncNotifyFilter$3.body(GridNioAsyncNotifyFilter.java:97)
> at
> org.apache.ignite.internal.util.worker.GridWorker.run(GridWorker.java:125)
> at
> org.apache.ignite.internal.util.worker.GridWorkerPool$1.run(GridWorkerPool.java:70)
> at
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
> at java.lang.Thread.run(Thread.java:748)
> Caused by: class
> org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerInaccessibleClassException:
> Failed to find class with given class loader for unmarshalling (make sure
> same versions of all classes are available on all nodes or enable
> peer-class-loading) [clsLdr=sun.misc.Launcher$AppClassLoader@18b4aac2,
> cls=Failed to resolve class name [platformId=0, platform=Java,
> typeId=-771474336]]
> at
> org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller.unmarshal0(OptimizedMarshaller.java:257)
> at
> org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller.unmarshal0(OptimizedMarshaller.java:225)
> at
> org.apache.ignite.marshaller.AbstractNodeNameAwareMarshaller.unmarshal(AbstractNodeNameAwareMarshaller.java:92)
> at
> org.apache.ignite.internal.binary.BinaryUtils.doReadOptimized(BinaryUtils.java:1816)
> ... 16 more
> Caused by: java.lang.ClassNotFoundException: Failed to resolve class name
> [platformId=0, platform=Java, typeId=-771474336]
> at
> org.apache.ignite.internal.MarshallerContextImpl.getClassName(MarshallerContextImpl.java:459)
> at
> org.apache.ignite.internal.MarshallerContextImpl.getClassName(MarshallerContextImpl.java:384)
> at
> org.apache.ignite.internal.MarshallerContextImpl.getClass(MarshallerContextImpl.java:371)
> at
> org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.descriptorFromCache(OptimizedMarshallerUtils.java:329)
> at
> org.apache.ignite.internal.marshaller.optimized.OptimizedMarshallerUtils.classDescriptor(OptimizedMarshallerUtils.java:274)
> at
> org.apache.ignite.internal.marshaller.optimized.OptimizedObjectInputStream.readObject0(OptimizedObjectInputStream.java:348)
> at
> org.apache.ignite.internal.marshaller.optimized.OptimizedObjectInputStream.readObjectOverride(OptimizedObjectInputStream.java:205)
> at java.io.ObjectInputStream.readObject(ObjectInputStream.java:494)
> at java.io.ObjectInputStream.readObject(ObjectInputStream.java:461)
> at
> org.apache.ignite.internal.marshaller.optimized.OptimizedMarshaller.unmarshal0(OptimizedMarshaller.java:251)
> ... 19 more
> [2021-08-04 23:22:44,698][WARN
> ][grid-nio-worker-client-listener-0-#90%client.ReliabilityTest%][ClientListenerProcessor]
> Failed to shutdown socket: null
> java.nio.channels.ClosedChannelException
> at
> sun.nio.ch.SocketChannelImpl.shutdownOutput(SocketChannelImpl.java:796)
> at sun.nio.ch.SocketAdaptor.shutdownOutput(SocketAdaptor.java:423)
> at
> org.apache.ignite.internal.util.IgniteUtils.close(IgniteUtils.java:4234)
> at
> org.apache.ignite.internal.util.nio.GridNioServer$AbstractNioClientWorker.closeKey(GridNioServer.java:2784)
> at
> org.apache.ignite.internal.util.nio.GridNioServer$AbstractNioClientWorker.close(GridNioServer.java:2835)
> at
> org.apache.ignite.internal.util.nio.GridNioServer$AbstractNioClientWorker.close(GridNioServer.java:2794)
> at
> org.apache.ignite.internal.util.nio.GridNioServer$AbstractNioClientWorker.bodyInternal(GridNioServer.java:2157)
> at
> org.apache.ignite.internal.util.nio.GridNioServer$AbstractNioClientWorker.body(GridNioServer.java:1910)
> at
> org.apache.ignite.internal.util.worker.GridWorker.run(GridWorker.java:125)
> at java.lang.Thread.run(Thread.java:748) {code}
> Root cause: client believes that it has registered the type within the
> cluster, but cluster can loose this information after failover if its working
> directory gets erased.
--
This message was sent by Atlassian Jira
(v8.3.4#803005)