开发者

How to send an inputStream object to Java EJBean?

I have a Java client for a session bean, I want to send it an inputStream as following:

Note: I am working with 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();
    }
}

}

but it throw the following exception:

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.so开发者_运维问答cket.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


As others have indicated, File, InputStream and many other IO-related objects are not serializable and therefore can't be stretched across the connection between client and server (without added functionality). In a J2EE context, the container should finish processes as quickly as possible to minimize resource usage and allow for parallel processing. Prior to Java's NIO, I/O operations typically blocked (waiting to read or write data), which caused threads to hang (i.e., temporarily stop running at best, permanently at worst).

I worked on a project once where some of the implementors, who were fairly new to Java, opened up FTP connections to remote servers from EJBs – against my warnings and those of the J2EE documentation. When a remote server did not respond, the only way to un-hang our server was to kill and re-start it!

Therefore: Grab the file contents in the client and ship it across the connection as a big String, or a character or byte array or something. That way, your EJB process will have the data all ready for processing.

If the amount of data is too big to do this in a reasonable amount of memory, then this is not a viable solution. The recommended solution in this case would be for the client to write the data into a database (perhaps a BLOB) and have the EJB read from the DB.


If you're using a remote EJB, then the parameter Objects are marshalled and unmarshalled (converted from Object to byte-stream, sent, then back to Object). This requires that all your parameters implement Serializable. Since a FileInputStream isn't serializable, it won't work as a parameter. You'll need to send the contents of the file in something like a String (a byte[] should also work, I believe).


To be sent across the wire, the arguments to the function on your session bean have to be serialized. A stream cannot be serialized (i.e. does not implement the Serializable interface), hence you will not be able to pass it to a remote bean.

To get the argument to a remote bean, you will have to use a serializable representation.


JBoss has a serialized input stream class.

This works to test a bean that uses an InputStream across a contracted interface.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜