{"action":"created","issue":{"url":"https://api.github.com/repos/payara/Payara/issues/1093","repository_url":"https://api.github.com/repos/payara/Payara","labels_url":"https://api.github.com/repos/payara/Payara/issues/1093/labels{/name}","comments_url":"https://api.github.com/repos/payara/Payara/issues/1093/comments","events_url":"https://api.github.com/repos/payara/Payara/issues/1093/events","html_url":"https://github.com/payara/Payara/issues/1093","id":176902030,"number":1093,"title":"Hazelcast serialization issue when sending events","user":{"login":"dorpsidioot","id":13536281,"avatar_url":"https://avatars.githubusercontent.com/u/13536281?v=3","gravatar_id":"","url":"https://api.github.com/users/dorpsidioot","html_url":"https://github.com/dorpsidioot","followers_url":"https://api.github.com/users/dorpsidioot/followers","following_url":"https://api.github.com/users/dorpsidioot/following{/other_user}","gists_url":"https://api.github.com/users/dorpsidioot/gists{/gist_id}","starred_url":"https://api.github.com/users/dorpsidioot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dorpsidioot/subscriptions","organizations_url":"https://api.github.com/users/dorpsidioot/orgs","repos_url":"https://api.github.com/users/dorpsidioot/repos","events_url":"https://api.github.com/users/dorpsidioot/events{/privacy}","received_events_url":"https://api.github.com/users/dorpsidioot/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":2,"created_at":"2016-09-14T13:05:38Z","updated_at":"2016-09-15T12:51:15Z","closed_at":null,"body":"We would like to be able to signal all the members of a hazelcast payara cluster that a certain resource has been invalidated and should be reloaded. Say for example that on node1 a request has arrived which causes an invalidation of the internal workings of a singleton implementation, then the other nodes have to do the same as node1.\r\n\r\nSo I was thinking of using the hazelcast functionality to do this, and it works to some degree:\r\n- I can get the HazelcastInstance from the JNDI context\r\n- I can create a new hazelcast topic\r\n- I can publish messages to that topic\r\n- I can receive messages from that topic in a different handler\r\n\r\nHowever, when the messages are something other than a default java class, it all goes down the drain. I then get these exceptions when trying to get the internal object from the message's instance:\r\ncom.hazelcast.nio.serialization.HazelcastSerializationException: java.lang.ClassNotFoundException.\r\n\r\nI've tried to set the classloader of hazelcast to the war's classloader but no avail. From what I can see when I debug is that the serialization works ok, because there he uses the correct classloader, but when it's deserialized then it's using the payara's classloader instead.\r\n\r\nThe singleton which instantiates the topics and sends the messages:\r\n```java\r\n@Singleton\r\n@Startup\r\n@LocalBean\r\npublic class HazelcastController {\r\n    \r\n    private HazelcastInstance hazelcastInstance;\r\n    private ITopic topic;\r\n    \r\n    private static final Logger log = Logger.getLogger(HazelcastController.class.getName());\r\n    \r\n    @PostConstruct\r\n    public void onInit() {\r\n        try {\r\n\r\n\t    log.log(Level.INFO, \"initializing {0}\", this.getClass().toString());\r\n\r\n\t    Context ctx = new InitialContext();\r\n\t    hazelcastInstance = (HazelcastInstance) ctx.lookup(\"payara/Hazelcast\");\r\n\t    if (hazelcastInstance != null) {\r\n\t\t// Setup classloader so it can find the necessary stuff\r\n\t\tConfig config = hazelcastInstance.getConfig();\r\n\t\tif (config != null) {\r\n\t\t    config.setClassLoader(Thread.currentThread().getContextClassLoader());\r\n\t\t}\t\t\r\n\t\ttopic = hazelcastInstance.getTopic(\"default\");\r\n\t\ttopic.addMessageListener(new HazelcastMessageListener());\r\n\r\n\t\tlog.log(Level.INFO, \"Done initializing {0}\", this.getClass().toString());\r\n\t    } else {\r\n\t\tlog.log(Level.SEVERE, \"Hazelcast instance not found\");\r\n\t    }\r\n        } catch (Exception ex) {\r\n            log.log(Level.SEVERE, \"An error has occurred while initializing HazelcastListener - Error: {0}\", ex.getMessage());\r\n        }\r\n    }\r\n    \r\n    @Schedule(second = \"0/15\", minute = \"*\", hour = \"*\")\r\n    public void sendMessage() {\r\n\tif (topic != null) {\r\n\t    topic.publish(new BasicEvent(\"TEST 123\"));\r\n\t}\r\n    }    \r\n}\r\n```\r\n\r\nThe message listener class:\r\n```java\r\npublic class HazelcastMessageListener implements MessageListener<BasicEvent> {\r\n\r\n    private static final Logger log = Logger.getLogger(HazelcastMessageListener.class.getName());\r\n    \r\n    @Override\r\n    public void onMessage(Message<BasicEvent> message) {\r\n\tif (message != null) {\r\n\t    log.log(Level.INFO, \"Received message from cluster member {0}\", message.getPublishingMember());\r\n\t    BasicEvent event = message.getMessageObject();\r\n\t    log.log(Level.INFO, \"Message: {0}\", event.getMessage());\r\n\t}\r\n    }\r\n    \r\n}\r\n```\r\n\r\nThe BasicEvent class(message object)\r\n```java\r\npublic class BasicEvent implements Serializable {    \r\n    private static final long serialVersionUID = 1L;\r\n    \r\n    private String message;\r\n\r\n    public String getMessage() {\r\n\treturn message;\r\n    }\r\n\r\n    public void setMessage(String message) {\r\n\tthis.message = message;\r\n    }\r\n    \r\n    protected BasicEvent() {}\r\n\r\n    public BasicEvent(String message) {\r\n\tthis.message = message;\r\n    }\r\n}\r\n```\r\n\r\nStack trace when the message is received\r\n```\r\nInfo: Received message from cluster member Member [192.168.0.249]:5900 this\r\nSevere: [192.168.0.249]:5900 [development] [3.6.4] hz._hzInstance_1_development.event-1 caught an exception while processing task:com.hazelcast.spi.impl.eventservice.impl.LocalEventDispatcher@47dfa96f\r\ncom.hazelcast.nio.serialization.HazelcastSerializationException: java.lang.ClassNotFoundException: be.powerdale.hazelcast.BasicEvent\r\n\tat com.hazelcast.internal.serialization.impl.JavaDefaultSerializers$JavaSerializer.read(JavaDefaultSerializers.java:224)\r\n\tat com.hazelcast.internal.serialization.impl.StreamSerializerAdapter.read(StreamSerializerAdapter.java:46)\r\n\tat com.hazelcast.internal.serialization.impl.AbstractSerializationService.toObject(AbstractSerializationService.java:170)\r\n\tat com.hazelcast.topic.impl.DataAwareMessage.getMessageObject(DataAwareMessage.java:44)\r\n\tat be.powerdale.hazelcast.HazelcastMessageListener.onMessage(HazelcastMessageListener.java:21)\r\n\tat com.hazelcast.topic.impl.TopicService.dispatchEvent(TopicService.java:131)\r\n\tat com.hazelcast.spi.impl.eventservice.impl.LocalEventDispatcher.run(LocalEventDispatcher.java:56)\r\n\tat com.hazelcast.util.executor.StripedExecutor$Worker.process(StripedExecutor.java:187)\r\n\tat com.hazelcast.util.executor.StripedExecutor$Worker.run(StripedExecutor.java:171)\r\nCaused by: java.lang.ClassNotFoundException: be.powerdale.hazelcast.BasicEvent\r\n\tat java.net.URLClassLoader.findClass(URLClassLoader.java:381)\r\n\tat java.lang.ClassLoader.loadClass(ClassLoader.java:424)\r\n\tat com.sun.enterprise.loader.CurrentBeforeParentClassLoader.loadClass(CurrentBeforeParentClassLoader.java:82)\r\n\tat java.lang.ClassLoader.loadClass(ClassLoader.java:357)\r\n\tat com.hazelcast.nio.ClassLoaderUtil.tryLoadClass(ClassLoaderUtil.java:137)\r\n\tat com.hazelcast.nio.ClassLoaderUtil.loadClass(ClassLoaderUtil.java:115)\r\n\tat com.hazelcast.nio.IOUtil$1.resolveClass(IOUtil.java:114)\r\n\tat java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1620)\r\n\tat java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1521)\r\n\tat java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1781)\r\n\tat java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1353)\r\n\tat java.io.ObjectInputStream.readObject(ObjectInputStream.java:373)\r\n\tat com.hazelcast.internal.serialization.impl.JavaDefaultSerializers$JavaSerializer.read(JavaDefaultSerializers.java:219)\r\n\t... 8 more\r\n```\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/payara/Payara/issues/comments/247319083","html_url":"https://github.com/payara/Payara/issues/1093#issuecomment-247319083","issue_url":"https://api.github.com/repos/payara/Payara/issues/1093","id":247319083,"user":{"login":"dorpsidioot","id":13536281,"avatar_url":"https://avatars.githubusercontent.com/u/13536281?v=3","gravatar_id":"","url":"https://api.github.com/users/dorpsidioot","html_url":"https://github.com/dorpsidioot","followers_url":"https://api.github.com/users/dorpsidioot/followers","following_url":"https://api.github.com/users/dorpsidioot/following{/other_user}","gists_url":"https://api.github.com/users/dorpsidioot/gists{/gist_id}","starred_url":"https://api.github.com/users/dorpsidioot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dorpsidioot/subscriptions","organizations_url":"https://api.github.com/users/dorpsidioot/orgs","repos_url":"https://api.github.com/users/dorpsidioot/repos","events_url":"https://api.github.com/users/dorpsidioot/events{/privacy}","received_events_url":"https://api.github.com/users/dorpsidioot/received_events","type":"User","site_admin":false},"created_at":"2016-09-15T12:51:15Z","updated_at":"2016-09-15T12:51:15Z","body":"I'll try by providing a custom serializer which gets the correct context or just send strings(json) or byte arrays which contain the data itself and deserialize them locally as you suggested(json has the advantage that it's easily kept backwards compatible)."}}
{"actor":{"display_login":"dorpsidioot"}}