How to send an inputStream object to Java EJBean?

10,176

Solution 1

JBoss has a serialized input stream class.

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

Solution 2

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.

Solution 3

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).

Share:
10,176
Moro
Author by

Moro

Updated on June 13, 2022

Comments

  • Moro
    Moro almost 2 years

    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.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