Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.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
like image 771
Moro Avatar asked Dec 07 '22 05:12

Moro


2 Answers

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.

like image 88
Carl Smotricz Avatar answered Dec 17 '22 11:12

Carl Smotricz


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

like image 34
Kaleb Brasee Avatar answered Dec 17 '22 12:12

Kaleb Brasee