如何将inputStream对象发送到Java EJBean?

时间:2009-12-07 21:12:15

标签: java java-ee ejb-3.0

我有一个会话bean的Java客户端,我想发送一个inputStream,如下所示:

注意:我正在使用EJB 3.0

public class SenderSimulator {

public static void main(String[] arg){
    Properties p = new Properties();
    p.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
    p.put("java.naming.provider.url", "jnp://localhost:1099");
    p.put("java.naming.factory.url.pkgs", "org.jboss.naming:org.jnp.interfaces");

    try {
        Context context = new InitialContext(p);
        RogersBatchImporter  bean = (RogersBatchImporter)context.lookup("RogersImporterBean/remote");
        InputStream in = new FileInputStream("filePath");           
        System.out.println("Result: " + bean.processBatch(in));  // line 29
    } catch (NamingException e) {
        e.printStackTrace();
    } catch (LogConfigurationException e) {
        e.printStackTrace();
    } catch (FileNotFoundException e) {
        e.printStackTrace();
    }
}

}

但它抛出以下异常:

Exception in thread "main" java.lang.reflect.UndeclaredThrowableException

at $Proxy0.processBatch(Unknown Source)

at package.main(SenderSimulator.java:29)

Caused by: java.rmi.MarshalException: Failed to communicate.  Problem during marshalling/unmarshalling; nested exception is: 
    java.io.NotSerializableException: java.io.FileInputStream
    at org.jboss.remoting.transport.socket.SocketClientInvoker.handleException(SocketClientInvoker.java:127)
    at org.jboss.remoting.transport.socket.MicroSocketClientInvoker.transport(MicroSocketClientInvoker.java:689)
    at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:122)
    at org.jboss.remoting.Client.invoke(Client.java:1634)
    at org.jboss.remoting.Client.invoke(Client.java:548)
    at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:62)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropagationInterceptor.java:67)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.aspects.security.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:53)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:74)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.ejb3.stateless.StatelessRemoteProxy.invoke(StatelessRemoteProxy.java:107)
    ... 2 more
Caused by: java.io.NotSerializableException: java.io.FileInputStream
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1156)
    at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1338)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1146)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
    at java.rmi.MarshalledObject.<init>(MarshalledObject.java:101)
    at org.jboss.aop.joinpoint.MethodInvocation.writeExternal(MethodInvocation.java:318)
    at java.io.ObjectOutputStream.writeExternalData(ObjectOutputStream.java:1421)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1390)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
    at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1509)
    at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1474)
    at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1392)
    at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1150)
    at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:326)
    at org.jboss.remoting.serialization.impl.java.JavaSerializationManager.sendObjectVersion2_2(JavaSerializationManager.java:120)
    at org.jboss.remoting.serialization.impl.java.JavaSerializationManager.sendObject(JavaSerializationManager.java:95)
    at org.jboss.remoting.marshal.serializable.SerializableMarshaller.write(SerializableMarshaller.java:120)
    at org.jboss.remoting.transport.socket.MicroSocketClientInvoker.versionedWrite(MicroSocketClientInvoker.java:969)
    at org.jboss.remoting.transport.socket.MicroSocketClientInvoker.transport(MicroSocketClientInvoker.java:606)
    at org.jboss.remoting.MicroRemoteClientInvoker.invoke(MicroRemoteClientInvoker.java:122)
    at org.jboss.remoting.Client.invoke(Client.java:1634)
    at org.jboss.remoting.Client.invoke(Client.java:548)
    at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:62)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropagationInterceptor.java:67)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.aspects.security.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:53)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:74)
    at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
    at org.jboss.ejb3.stateless.StatelessRemoteProxy.invoke(StatelessRemoteProxy.java:107)
    at $Proxy0.processBatch(Unknown Source)
    at com.cybersource.rogers.batch.request.SenderSimulator.main(SenderSimulator.java:29)
    at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:74)
    ... 10 more

4 个答案:

答案 0 :(得分:12)

正如其他人所指出的那样,FileInputStream和许多其他与IO相关的对象不可序列化,因此无法在客户端和服务器之间的连接上进行扩展(没有添加功能)。在J2EE上下文中,容器应尽快完成进程以最小化资源使用并允许并行处理。在Java NIO之前,I / O操作通常被阻塞(等待读取或写入数据),这导致线程挂起(即,最好暂时停止运行,最坏情况下永久运行)。

我曾经在一个项目上工作,其中一些对Java来说相当新的实现者打开了与EJB远程服务器的FTP连接 - 违反我的警告和J2EE文档的警告。当远程服务器没有响应时,取消挂起我们服务器的唯一方法就是杀死并重新启动它!

因此:抓取客户端中的文件内容,并将其作为大字符串或字符或字节数组或其他内容通过连接发送。这样,您的EJB进程就可以准备好处理数据了。

如果数据量太大而无法在合理的内存量中执行此操作,那么这不是一个可行的解决方案。在这种情况下,推荐的解决方案是客户端将数据写入数据库(可能是BLOB)并从数据库中读取EJB。

答案 1 :(得分:3)

如果您正在使用远程EJB,则参数Objects将被编组和解组(从Object转换为字节流,发​​送,然后再转换回Object)。这要求您的所有参数都实现Serializable。由于FileInputStream不可序列化,因此它不能用作参数。您需要以类似String的形式发送文件的内容(我相信byte []也应该有效。)

答案 2 :(得分:0)

要通过网络发送,会话bean上函数的参数必须为serialized。流无法序列化(即未实现Serializable接口),因此您将无法将其传递给远程bean。

要获取远程bean的参数,您必须使用可序列化的表示。

答案 3 :(得分:0)

JBoss有一个serialized input stream类。

这适用于测试在签约接口上使用InputStream的bean。