Catch user exception in remote service at caller level

允我心安 提交于 2019-12-12 05:35:01

问题


I am running multiple services in an Ignite cluster which depend on each other.

I'd like to catch (user defined) exceptions at caller level when I call a remote service function. See example based on the Service example in the docs for 1.7.

MyUserException.java

package com.example.testing;

public class MyUserException extends Throwable {}

MyCounterService.java

package com.example.testing;

public interface MyCounterService {
    int increment() throws MyUserException;
}

MyCounterServiceImpl.java (Error condition is ignite.cluster().forYoungest())

package com.example.testing;

import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteServices;
import org.apache.ignite.Ignition;
import org.apache.ignite.resources.IgniteInstanceResource;
import org.apache.ignite.services.Service;
import org.apache.ignite.services.ServiceContext;

public class MyCounterServiceImpl implements MyCounterService, Service {

    @IgniteInstanceResource
    private Ignite ignite;

    private int value = 0;

    public int increment() throws MyUserException {
        if ((value % 2) == 0) {
            throw new MyUserException();
        } else {
            value++;
        }
        return value;
    }

    public static void main(String [] args) {
        Ignite ignite = Ignition.start();
        IgniteServices svcs = ignite.services(ignite.cluster().forYoungest());
        svcs.deployNodeSingleton("MyCounterService", new MyCounterServiceImpl());
    }

    @Override
    public void cancel(ServiceContext ctx) {
        System.out.println("Service cancelled");
    }

    @Override
    public void init(ServiceContext ctx) throws Exception {
        System.out.println("Service initialized");
    }

    @Override
    public void execute(ServiceContext ctx) throws Exception {
        System.out.println("Service running");
    }
}

MyCallerService.java

package com.example.testing;

import org.apache.ignite.Ignite;
import org.apache.ignite.IgniteException;
import org.apache.ignite.Ignition;
import org.apache.ignite.resources.IgniteInstanceResource;
import org.apache.ignite.services.Service;
import org.apache.ignite.services.ServiceContext;

public class MyCallerService implements Service {

    @IgniteInstanceResource
    private Ignite ignite;

    private Boolean stopped;

    public void run() {
        stopped = false;
        MyCounterService service = ignite.services().serviceProxy("MyCounterService", MyCounterService.class, false);
        while (!stopped)
        {
            try {
                Thread.sleep(500);
                service.increment();
            } catch (MyUserException e) {
                System.out.println("Got exception");
                //e.printStackTrace();
            } catch (InterruptedException e) {
                //e.printStackTrace();
            }
            catch (IgniteException e) {
                System.out.println("Got critial exception");
                // would print the actual user exception
                //e.getCause().getCause().getCause().printStackTrace();
                break;
            }
        }
    }

    public static void main(String [] args) {
        Ignite ignite = Ignition.start();
        ignite.services(ignite.cluster().forYoungest()).deployNodeSingleton("MyCallerService", new MyCallerService());
    }

    @Override
    public void cancel(ServiceContext ctx) {
        stopped = true;
    }

    @Override
    public void init(ServiceContext ctx) throws Exception {

    }

    @Override
    public void execute(ServiceContext ctx) throws Exception {
        run();
    }
}

The exception is not being catched at the caller level. Instead these exceptions show up in the console. How do I catch and handle the exceptions properly when a service function is called?

Output of MyCounterServiceImpl

[18:23:23] Ignite node started OK (id=c82df19c)
[18:23:23] Topology snapshot [ver=1, servers=1, clients=0, CPUs=4, heap=3.5GB]
Service initialized
Service running
[18:23:27] Topology snapshot [ver=2, servers=2, clients=0, CPUs=4, heap=7.0GB]
Nov 17, 2016 6:23:28 PM org.apache.ignite.logger.java.JavaLogger error
SCHWERWIEGEND: Failed to execute job [jobId=82580537851-3c0a354f-69b5-496c-af10-ee789a5387c3, ses=GridJobSessionImpl [ses=GridTaskSessionImpl [taskName=o.a.i.i.processors.service.GridServiceProxy$ServiceProxyCallable, dep=LocalDeployment [super=GridDeployment [ts=1479403401422, depMode=SHARED, clsLdr=sun.misc.Launcher$AppClassLoader@1d44bcfa, clsLdrId=4fe60537851-c82df19c-cdff-43ef-b7b6-e8485231629a, userVer=0, loc=true, sampleClsName=java.lang.String, pendingUndeploy=false, undeployed=false, usage=0]], taskClsName=o.a.i.i.processors.service.GridServiceProxy$ServiceProxyCallable, sesId=72580537851-3c0a354f-69b5-496c-af10-ee789a5387c3, startTime=1479403408961, endTime=9223372036854775807, taskNodeId=3c0a354f-69b5-496c-af10-ee789a5387c3, clsLdr=sun.misc.Launcher$AppClassLoader@1d44bcfa, closed=false, cpSpi=null, failSpi=null, loadSpi=null, usage=1, fullSup=false, subjId=3c0a354f-69b5-496c-af10-ee789a5387c3, mapFut=IgniteFuture [orig=GridFutureAdapter [resFlag=0, res=null, startTime=1479403408960, endTime=0, ignoreInterrupts=false, state=INIT]]], jobId=82580537851-3c0a354f-69b5-496c-af10-ee789a5387c3]]
class org.apache.ignite.IgniteException: null
    at org.apache.ignite.internal.processors.closure.GridClosureProcessor$C2V2.execute(GridClosureProcessor.java:2009)
    at org.apache.ignite.internal.processors.job.GridJobWorker$2.call(GridJobWorker.java:509)
    at org.apache.ignite.internal.util.IgniteUtils.wrapThreadLoader(IgniteUtils.java:6521)
    at org.apache.ignite.internal.processors.job.GridJobWorker.execute0(GridJobWorker.java:503)
    at org.apache.ignite.internal.processors.job.GridJobWorker.body(GridJobWorker.java:456)
    at org.apache.ignite.internal.util.worker.GridWorker.run(GridWorker.java:110)
    at org.apache.ignite.internal.processors.job.GridJobProcessor.processJobExecuteRequest(GridJobProcessor.java:1161)
    at org.apache.ignite.internal.processors.job.GridJobProcessor$JobExecutionListener.onMessage(GridJobProcessor.java:1766)
    at org.apache.ignite.internal.managers.communication.GridIoManager.invokeListener(GridIoManager.java:1238)
    at org.apache.ignite.internal.managers.communication.GridIoManager.processRegularMessage0(GridIoManager.java:866)
    at org.apache.ignite.internal.managers.communication.GridIoManager.access$1700(GridIoManager.java:106)
    at org.apache.ignite.internal.managers.communication.GridIoManager$5.run(GridIoManager.java:829)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.ignite.internal.processors.service.GridServiceProxy$ServiceProxyCallable.call(GridServiceProxy.java:392)
    at org.apache.ignite.internal.processors.closure.GridClosureProcessor$C2V2.execute(GridClosureProcessor.java:2006)
    ... 14 more
Caused by: com.example.testing.MyUserException
    at com.example.testing.MyCounterServiceImpl.increment(MyCounterServiceImpl.java:19)
    ... 20 more

Output of MyCallerService

[18:23:28] Ignite node started OK (id=3c0a354f)
[18:23:28] Topology snapshot [ver=2, servers=2, clients=0, CPUs=4, heap=7.0GB]
Nov 17, 2016 6:23:28 PM org.apache.ignite.logger.java.JavaLogger error
SCHWERWIEGEND: Failed to obtain remote job result policy for result from ComputeTask.result(..) method (will fail the whole task): GridJobResultImpl [job=C2V2 [c=ServiceProxyCallable [mtdName=increment, svcName=MyCounterService, ignite=null]], sib=GridJobSiblingImpl [sesId=72580537851-3c0a354f-69b5-496c-af10-ee789a5387c3, jobId=82580537851-3c0a354f-69b5-496c-af10-ee789a5387c3, nodeId=c82df19c-cdff-43ef-b7b6-e8485231629a, isJobDone=false], jobCtx=GridJobContextImpl [jobId=82580537851-3c0a354f-69b5-496c-af10-ee789a5387c3, timeoutObj=null, attrs={}], node=TcpDiscoveryNode [id=c82df19c-cdff-43ef-b7b6-e8485231629a, addrs=[0:0:0:0:0:0:0:1%lo, 127.0.0.1, 172.18.22.52], sockAddrs=[/0:0:0:0:0:0:0:1%lo:47500, /127.0.0.1:47500, /172.18.22.52:47500], discPort=47500, order=1, intOrder=1, lastExchangeTime=1479403407847, loc=false, ver=1.7.0#20160801-sha1:383273e3, isClient=false], ex=class o.a.i.IgniteException: null, hasRes=true, isCancelled=false, isOccupied=true]
class org.apache.ignite.IgniteException: Remote job threw user exception (override or implement ComputeTask.result(..) method if you would like to have automatic failover for this exception).
    at org.apache.ignite.compute.ComputeTaskAdapter.result(ComputeTaskAdapter.java:101)
    at org.apache.ignite.internal.processors.task.GridTaskWorker$4.apply(GridTaskWorker.java:946)
    at org.apache.ignite.internal.processors.task.GridTaskWorker$4.apply(GridTaskWorker.java:939)
    at org.apache.ignite.internal.util.IgniteUtils.wrapThreadLoader(IgniteUtils.java:6553)
    at org.apache.ignite.internal.processors.task.GridTaskWorker.result(GridTaskWorker.java:939)
    at org.apache.ignite.internal.processors.task.GridTaskWorker.onResponse(GridTaskWorker.java:810)
    at org.apache.ignite.internal.processors.task.GridTaskProcessor.processJobExecuteResponse(GridTaskProcessor.java:995)
    at org.apache.ignite.internal.processors.task.GridTaskProcessor$JobMessageListener.onMessage(GridTaskProcessor.java:1220)
    at org.apache.ignite.internal.managers.communication.GridIoManager.invokeListener(GridIoManager.java:1238)
    at org.apache.ignite.internal.managers.communication.GridIoManager.processRegularMessage0(GridIoManager.java:866)
    at org.apache.ignite.internal.managers.communication.GridIoManager.access$1700(GridIoManager.java:106)
    at org.apache.ignite.internal.managers.communication.GridIoManager$5.run(GridIoManager.java:829)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: class org.apache.ignite.IgniteException: null
    at org.apache.ignite.internal.processors.closure.GridClosureProcessor$C2V2.execute(GridClosureProcessor.java:2009)
    at org.apache.ignite.internal.processors.job.GridJobWorker$2.call(GridJobWorker.java:509)
    at org.apache.ignite.internal.util.IgniteUtils.wrapThreadLoader(IgniteUtils.java:6521)
    at org.apache.ignite.internal.processors.job.GridJobWorker.execute0(GridJobWorker.java:503)
    at org.apache.ignite.internal.processors.job.GridJobWorker.body(GridJobWorker.java:456)
    at org.apache.ignite.internal.util.worker.GridWorker.run(GridWorker.java:110)
    at org.apache.ignite.internal.processors.job.GridJobProcessor.processJobExecuteRequest(GridJobProcessor.java:1161)
    at org.apache.ignite.internal.processors.job.GridJobProcessor$JobExecutionListener.onMessage(GridJobProcessor.java:1766)
    ... 7 more
Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.ignite.internal.processors.service.GridServiceProxy$ServiceProxyCallable.call(GridServiceProxy.java:392)
    at org.apache.ignite.internal.processors.closure.GridClosureProcessor$C2V2.execute(GridClosureProcessor.java:2006)
    ... 14 more
Caused by: com.example.testing.MyUserException
    at com.example.testing.MyCounterServiceImpl.increment(MyCounterServiceImpl.java:19)
    ... 20 more

Got critial exception

Apperently this is a bug that's to be resolved: https://issues.apache.org/jira/browse/IGNITE-4298


回答1:


i think exception must throw over to caller node. Could you please provide full code example? Also, so strange that on node which have service, was exception with null value.

UPD.

Could you please also add log, because fort me, all work as expected. I catched MyUserException, and have in log message "Got exception".



来源:https://stackoverflow.com/questions/40545051/catch-user-exception-in-remote-service-at-caller-level

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!