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
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With