1

应用程序可以调用通过非Mule 线程(即应用​​程序创建的线程)上的组件绑定创建的代理吗?我正在尝试这样做,但我在 org.mule.DefaultMuleEvent:268 上得到了 NullPointerException。

在 Mule EE 3.3.0 上

谢谢。

更新:

骡代码

<mule ...>
    <vm:endpoint path="entryPoint" name="entryPoint" />

    <flow name="entryPoint.Flow">
        <inbound-endpoint ref="entryPoint" exchange-pattern="request-response" />
        <component class="foo.Component">
            <binding interface="foo.Interface" method="echo">
            <vm:outbound-endpoint path="foo.Interface.echo" exchange-pattern="request-response" />
        </binding>
        </component>
    </flow>

    <flow name="foo.Interface.echo">
        <vm:inbound-endpoint path="foo.Interface.echo" exchange-pattern="request-response" />
        <logger level="INFO" />
    </flow>

</mule>

Java 组件

package foo;

import static java.util.concurrent.Executors.newSingleThreadExecutor;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

public class Component {

    private Interface i;

    public String foo(final String input) {
        return callInterfaceOnAWorkerThreadWith(input);
    }

    public void setInterface(final Interface i) {
        this.i = i;
    }

    private String callInterfaceOnAWorkerThreadWith(final String input) {
        ExecutorService executorService = newSingleThreadExecutor();
        Future<String> future = executorService.submit(new Callable<String>() {

            @Override
            public String call() throws Exception {
                return i.echo(input);
            }

        });
        executorService.shutdown();
        try {
            executorService.awaitTermination(60, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        try {
            return future.get();
        } catch (InterruptedException | ExecutionException e) {
            throw new RuntimeException(e);
        }

    }

}

Java 接口

package foo;

public interface Interface {

    String echo(String input);

}

执行 mule 应用程序的测试夹具

package foo;

import static org.junit.Assert.assertEquals;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
import org.mule.api.MuleException;
import org.mule.api.MuleMessage;
import org.mule.api.client.MuleClient;
import org.mule.tck.junit4.FunctionalTestCase;

@RunWith(MockitoJUnitRunner.class)
public class ATest extends FunctionalTestCase {

    @Test
    public void echo() {
        final MuleClient client = muleContext.getClient();
        MuleMessage reply = send(client, "entryPoint", "a string");
        assertEquals("a string", reply.getPayload());
    }

    @Override
    protected String getConfigResources() {
        return "app/componentbindingonanotherthread.xml";
    }

    private MuleMessage send(final MuleClient client, final String url, final Object payload) {
        try {
            return client.send(url, payload, null, RECEIVE_TIMEOUT);
        } catch (final MuleException e) {
            throw new RuntimeException(e);
        }
    }

}

执行上面的代码会在日志中显示以下异常:

Root Exception stack trace:
java.lang.NullPointerException
    at org.mule.DefaultMuleEvent.<init>(DefaultMuleEvent.java:268)
    at org.mule.component.BindingInvocationHandler.invoke(BindingInvocationHandler.java:96)
    at $Proxy14.echo(Unknown Source)
4

1 回答 1

1

问题归结为 Mule通过 usingBindingInvocationHandler查找电流,这是-bound。换句话说,由于您在另一个线程中执行绑定,所以 Mule 上下文会丢失,并且您会遇到上述失败。MuleEventRequestContext.getEvent()ThreadLocal

使用 Mule 的工人管理器(您可以从 MuleContext 获得),这将是使用您自己的更好的设计ExecutorService,但仍然无法解决问题,因为依赖BindingInvocationHandler于(已弃用!)RequestContext.getEvent()构造。

我认为您需要重新考虑您的设计,因为当您真正研究它时,IMO 没有多大意义。在另一个线程上执行绑定不会给您带来任何好处,因为它entryPoint是请求-响应,因此入站线程被从池中调动。在绑定完成之前,该线程保持阻塞状态,无论绑定本身是由该线程还是由另一个线程执行。

如果出于我无法理解的原因,您确实需要在另一个线程中执行绑定,则将绑定移动到另一个流中并使用request-reply消息处理器调用它。

这里的教训是:Mule 已经拥有丰富的线程模型,最好使用它提供的线程结构(request-reply、、 VM 队列)在其中发挥作用asyncone-way而不是编写自己的代码。

于 2012-11-23T17:47:43.893 回答