Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Custom exception not transported to the hazelcast client (disributed executor service) -> instead UndefinedErrorCodeException #9753

Closed
Petikoch opened this issue Jan 25, 2017 · 12 comments · Fixed by #17556
Assignees
Milestone

Comments

@Petikoch
Copy link

Petikoch commented Jan 25, 2017

If I use the hazelcast client to call the distributed executor service and the callable throws an exception with a custom type, the exception is not transported to the client. The cause of the ExecutionException is then not "my exception", instead it is UndefinedErrorCodeException. The class of "my exception" is both in the classpath of the "server" and of the "client".

If I do the same using a regular hazelcast node (not the client), everything works.

How can I let transport "my exception" as cause to the hazelcast client?

See the below example to show the issue (using hazelcast and hazelcast-client 3.7.5):

import com.hazelcast.client.HazelcastClient;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;

import java.io.Serializable;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

public class CustomExceptionIssueWithHazelcastClient {

	public static void main(String[] args) throws InterruptedException {
		HazelcastInstance hzServer = Hazelcast.newHazelcastInstance();
		hzServer.getCluster().getLocalMember().setStringAttribute("type", "server");

		// does not work
		HazelcastInstance hzClient = HazelcastClient.newHazelcastClient();
		// works, in constrast:
		// HazelcastInstance hzClient = Hazelcast.newHazelcastInstance();

		try {
			hzClient.getExecutorService("Default").submit(
					new ThrowingCallable(),
					member -> {
						final String memberAttr = member.getStringAttribute("type");
						return memberAttr != null && memberAttr.equals("server");
					}
			).get();
		}  catch (ExecutionException e) {
			if(!(e.getCause() instanceof CustomRuntimeException)){
				System.out.println("Wrong exception type here! " );
				e.printStackTrace();
				TimeUnit.SECONDS.sleep(5);
			}
		} finally {
			hzClient.shutdown();
			hzServer.shutdown();
		}
	}

	public static class CustomRuntimeException extends RuntimeException {
	}

	public static class ThrowingCallable implements Callable<String>, Serializable {

		@Override
		public String call() throws Exception {
			throw new CustomRuntimeException();
		}
	}
}
@Petikoch
Copy link
Author

Petikoch commented Mar 9, 2017

#9713 seems to go in the right direction, am I right?

@sancar sancar added this to the Backlog milestone Mar 14, 2017
@sancar sancar modified the milestones: 3.9, Backlog Aug 1, 2017
@sancar
Copy link
Contributor

sancar commented Aug 2, 2017

When we switched to protocol to support all languages, exceptions support get weakened. Before we were using Java Serialization directly. Right now, we are using our own description for exceptions. For the exceptions are not defined in protocol, we are delivering them via UndefinedErrorCodeException which has the original class name as field.

More extensive work on this will be done on 4.0.

#9713 is a workaround to be used internally. One idea is to make this public in 4.0 to be used by our users.

@sancar sancar modified the milestones: 4.0, 3.9 Aug 2, 2017
@burakcelebi burakcelebi added Source: Community PR or issue was opened by a community user Priority: Low labels Jan 3, 2018
@burakcelebi burakcelebi modified the milestones: 4.0, 3.11 Feb 9, 2018
@dbrimley
Copy link
Contributor

dbrimley commented Apr 3, 2018

@sancar Would this enhancement mean breaking the client protocol? Should it be just in 4.0 or can at least some research be carried out in 3.11 phase?

@sancar
Copy link
Contributor

sancar commented Apr 3, 2018

It feels like we can find a way to not to break the protocol when introducing the change.
So 3.11 could be an option.

@burakcelebi burakcelebi modified the milestones: 3.11, 3.12 May 17, 2018
@Petikoch
Copy link
Author

I just fell into this problem again, when trying to migrate code which was working using a hazelcast-lite-member into code which uses a hazelcast client instead.

Exception handling was broken... and I had to extend the catch block to fix it.

It would be really nice if the same API (HazelcastInstance#getExecutorService ... submit ...) would behave the same way, also regarding exceptions, in hazelcast AND in hazelcast-client.

I'm looking forward to 3.11! :-)

@sancar
Copy link
Contributor

sancar commented Sep 27, 2018

@Petikoch Sorry to inform you that we could not prioritize this one and it is postponed.
And whether this will be on 3.12 or later is not decided yet.

@dbrimley
Copy link
Contributor

@sancar although this didn't make it into 3.11 due to time constraints, is this a client side only fix? Therefore it might be possible to release in a 3.11.1 of the Java Client? Trying to think of ways to get this to @Petikoch as soon as possible.

@sancar
Copy link
Contributor

sancar commented Sep 27, 2018

@dbrimley
This seems to require new configuration on both server and client for users to register their classes.

@dbrimley dbrimley modified the milestones: 3.12, 3.13 Nov 8, 2018
@mmedenjak mmedenjak modified the milestones: 3.13, 4.0 Apr 17, 2019
@ihsandemir ihsandemir self-assigned this Nov 5, 2019
ihsandemir added a commit to ihsandemir/hazelcast that referenced this issue Nov 6, 2019
@ihsandemir ihsandemir removed their assignment Nov 20, 2019
@ihsandemir ihsandemir modified the milestones: 4.0, Backlog, 4.1 Nov 20, 2019
@sancar sancar modified the milestones: 4.1, Backlog Feb 18, 2020
@Holmistr Holmistr modified the milestones: 4.1, 4.2 Aug 25, 2020
@javanotes
Copy link

Hi Team, has this been put into formal solution? I am experiencing this in 4.0.2

@mmedenjak mmedenjak modified the milestones: 4.2, 4.1 Aug 28, 2020
sancar pushed a commit to sancar/hazelcast that referenced this issue Sep 16, 2020
We are throwing UndefinedErrorCodeException if an exception is
not on the protocol list.

This causes poor experience as the behaviour is different between
the client and the member.

see  hazelcast#9753

This pr does not introduce an ExceptionFactory API as discussed
on the issue.
The value of an ExceptionFactory API is debetable and left out
for now. If the client has the expcetion class on the classpath,
the client will create it. If it is not available on the classpath,
it is not clear what can a user do with ExceptionFactory API.
In that case, we are throwing UndefinedErrorCodeException as before.
The main problem seems to be the case where the client have the
exact same class on the classpath, so this fix should cover
most of the use cases.

fixes hazelcast#9753
@sancar sancar self-assigned this Sep 16, 2020
sancar pushed a commit to sancar/hazelcast that referenced this issue Sep 24, 2020
We are throwing UndefinedErrorCodeException if an exception is
not on the protocol list.

This causes poor experience as the behaviour is different between
the client and the member.

see  hazelcast#9753

This pr does not introduce an ExceptionFactory API as discussed
on the issue.
The value of an ExceptionFactory API is debetable and left out
for now. If the client has the expcetion class on the classpath,
the client will create it. If it is not available on the classpath,
it is not clear what can a user do with ExceptionFactory API.
In that case, we are throwing UndefinedErrorCodeException as before.
The main problem seems to be the case where the client have the
exact same class on the classpath, so this fix should cover
most of the use cases.

Also added  assert to check if exception is defined in the protocol
When classLoading is introduced it is possible for us to forget
to put the exception in the protocol, because it will not longer
throw UndefinedErrorCodeException but it will be loaded
automatically.
Assertion is added to check and warn us.

fixes hazelcast#9753
sancar pushed a commit to sancar/hazelcast that referenced this issue Sep 24, 2020
We are throwing UndefinedErrorCodeException if an exception is
not on the protocol list.

This causes poor experience as the behaviour is different between
the client and the member.

see  hazelcast#9753

This pr does not introduce an ExceptionFactory API as discussed
on the issue.
The value of an ExceptionFactory API is debetable and left out
for now. If the client has the expcetion class on the classpath,
the client will create it. If it is not available on the classpath,
it is not clear what can a user do with ExceptionFactory API.
In that case, we are throwing UndefinedErrorCodeException as before.
The main problem seems to be the case where the client have the
exact same class on the classpath, so this fix should cover
most of the use cases.

Also added  assert to check if exception is defined in the protocol
When classLoading is introduced it is possible for us to forget
to put the exception in the protocol, because it will not longer
throw UndefinedErrorCodeException but it will be loaded
automatically.
Assertion is added to check and warn us.

fixes hazelcast#9753

(cherry picked from commit 18dd1dd)
sancar pushed a commit to sancar/hazelcast that referenced this issue Sep 24, 2020
We are throwing UndefinedErrorCodeException if an exception is
not on the protocol list.

This causes poor experience as the behaviour is different between
the client and the member.

see  hazelcast#9753

This pr does not introduce an ExceptionFactory API as discussed
on the issue.
The value of an ExceptionFactory API is debetable and left out
for now. If the client has the expcetion class on the classpath,
the client will create it. If it is not available on the classpath,
it is not clear what can a user do with ExceptionFactory API.
In that case, we are throwing UndefinedErrorCodeException as before.
The main problem seems to be the case where the client have the
exact same class on the classpath, so this fix should cover
most of the use cases.

Also added  assert to check if exception is defined in the protocol
When classLoading is introduced it is possible for us to forget
to put the exception in the protocol, because it will not longer
throw UndefinedErrorCodeException but it will be loaded
automatically.
Assertion is added to check and warn us.

fixes hazelcast#9753

(cherry picked from commit 18dd1dd)
sancar pushed a commit to sancar/hazelcast that referenced this issue Sep 25, 2020
We are throwing UndefinedErrorCodeException if an exception is
not on the protocol list.

This causes poor experience as the behaviour is different between
the client and the member.

see  hazelcast#9753

This pr does not introduce an ExceptionFactory API as discussed
on the issue.
The value of an ExceptionFactory API is debetable and left out
for now. If the client has the expcetion class on the classpath,
the client will create it. If it is not available on the classpath,
it is not clear what can a user do with ExceptionFactory API.
In that case, we are throwing UndefinedErrorCodeException as before.
The main problem seems to be the case where the client have the
exact same class on the classpath, so this fix should cover
most of the use cases.

Also added  assert to check if exception is defined in the protocol
When classLoading is introduced it is possible for us to forget
to put the exception in the protocol, because it will not longer
throw UndefinedErrorCodeException but it will be loaded
automatically.
Assertion is added to check and warn us.

fixes hazelcast#9753
sancar pushed a commit to sancar/hazelcast that referenced this issue Sep 28, 2020
We are throwing UndefinedErrorCodeException if an exception is
not on the protocol list.

This causes poor experience as the behaviour is different between
the client and the member.

see  hazelcast#9753

This pr does not introduce an ExceptionFactory API as discussed
on the issue.
The value of an ExceptionFactory API is debetable and left out
for now. If the client has the expcetion class on the classpath,
the client will create it. If it is not available on the classpath,
it is not clear what can a user do with ExceptionFactory API.
In that case, we are throwing UndefinedErrorCodeException as before.
The main problem seems to be the case where the client have the
exact same class on the classpath, so this fix should cover
most of the use cases.

Also added  assert to check if exception is defined in the protocol
When classLoading is introduced it is possible for us to forget
to put the exception in the protocol, because it will not longer
throw UndefinedErrorCodeException but it will be loaded
automatically.
Assertion is added to check and warn us.

fixes hazelcast#9753
sancar pushed a commit to sancar/hazelcast that referenced this issue Oct 2, 2020
We are throwing UndefinedErrorCodeException if an exception is
not on the protocol list.

This causes poor experience as the behaviour is different between
the client and the member.

see  hazelcast#9753

This pr does not introduce an ExceptionFactory API as discussed
on the issue.
The value of an ExceptionFactory API is debetable and left out
for now. If the client has the expcetion class on the classpath,
the client will create it. If it is not available on the classpath,
it is not clear what can a user do with ExceptionFactory API.
In that case, we are throwing UndefinedErrorCodeException as before.
The main problem seems to be the case where the client have the
exact same class on the classpath, so this fix should cover
most of the use cases.

Also added  assert to check if exception is defined in the protocol
When classLoading is introduced it is possible for us to forget
to put the exception in the protocol, because it will not longer
throw UndefinedErrorCodeException but it will be loaded
automatically.
Assertion is added to check and warn us.

fixes hazelcast#9753

(cherry picked from commit 18dd1dd)
sancar pushed a commit to sancar/hazelcast that referenced this issue Oct 2, 2020
We are throwing UndefinedErrorCodeException if an exception is
not on the protocol list.

This causes poor experience as the behaviour is different between
the client and the member.

see  hazelcast#9753

This pr does not introduce an ExceptionFactory API as discussed
on the issue.
The value of an ExceptionFactory API is debetable and left out
for now. If the client has the expcetion class on the classpath,
the client will create it. If it is not available on the classpath,
it is not clear what can a user do with ExceptionFactory API.
In that case, we are throwing UndefinedErrorCodeException as before.
The main problem seems to be the case where the client have the
exact same class on the classpath, so this fix should cover
most of the use cases.

Also added  assert to check if exception is defined in the protocol
When classLoading is introduced it is possible for us to forget
to put the exception in the protocol, because it will not longer
throw UndefinedErrorCodeException but it will be loaded
automatically.
Assertion is added to check and warn us.

fixes hazelcast#9753
sancar pushed a commit that referenced this issue Oct 5, 2020
* Try load custom exceptions via class loader on client

We are throwing UndefinedErrorCodeException if an exception is
not on the protocol list.

This causes poor experience as the behaviour is different between
the client and the member.

see  #9753

This pr does not introduce an ExceptionFactory API as discussed
on the issue.
The value of an ExceptionFactory API is debetable and left out
for now. If the client has the expcetion class on the classpath,
the client will create it. If it is not available on the classpath,
it is not clear what can a user do with ExceptionFactory API.
In that case, we are throwing UndefinedErrorCodeException as before.
The main problem seems to be the case where the client have the
exact same class on the classpath, so this fix should cover
most of the use cases.

Also added  assert to check if exception is defined in the protocol
When classLoading is introduced it is possible for us to forget
to put the exception in the protocol, because it will not longer
throw UndefinedErrorCodeException but it will be loaded
automatically.
Assertion is added to check and warn us.

fixes #9753

(cherry picked from commit 18dd1dd)
sancar pushed a commit that referenced this issue Oct 5, 2020
* Try load custom exceptions via class loader on client

We are throwing UndefinedErrorCodeException if an exception is
not on the protocol list.

This causes poor experience as the behaviour is different between
the client and the member.

see  #9753

This pr does not introduce an ExceptionFactory API as discussed
on the issue.
The value of an ExceptionFactory API is debetable and left out
for now. If the client has the expcetion class on the classpath,
the client will create it. If it is not available on the classpath,
it is not clear what can a user do with ExceptionFactory API.
In that case, we are throwing UndefinedErrorCodeException as before.
The main problem seems to be the case where the client have the
exact same class on the classpath, so this fix should cover
most of the use cases.

Also added  assert to check if exception is defined in the protocol
When classLoading is introduced it is possible for us to forget
to put the exception in the protocol, because it will not longer
throw UndefinedErrorCodeException but it will be loaded
automatically.
Assertion is added to check and warn us.

fixes #9753
sancar pushed a commit that referenced this issue Oct 6, 2020
* Try load custom exceptions via class loader on client

We are throwing UndefinedErrorCodeException if an exception is
not on the protocol list.

This causes poor experience as the behaviour is different between
the client and the member.

see  #9753

This pr does not introduce an ExceptionFactory API as discussed
on the issue.
The value of an ExceptionFactory API is debetable and left out
for now. If the client has the expcetion class on the classpath,
the client will create it. If it is not available on the classpath,
it is not clear what can a user do with ExceptionFactory API.
In that case, we are throwing UndefinedErrorCodeException as before.
The main problem seems to be the case where the client have the
exact same class on the classpath, so this fix should cover
most of the use cases.

Also added  assert to check if exception is defined in the protocol
When classLoading is introduced it is possible for us to forget
to put the exception in the protocol, because it will not longer
throw UndefinedErrorCodeException but it will be loaded
automatically.
Assertion is added to check and warn us.

fixes #9753
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment