4 Replies Latest reply on Dec 14, 2010 3:33 PM by ron_sigal

    JBoss remoting integration with legacy systems

    eliezerreis

      Hi,

      I need implement a server socket to do integration between 3 systems implemented in languages diferent (C#, Delphi). I already implemented all functionality (existe thread in this functionality ) in one desktop application (using api java.net) for more fast debug and test. When I went include this functionality in my web applications (.war) in JBoss AS a lot of problems happened. Then i'd like knows if it's possible with JBoss Remoting:

      1) Is possible run jboss remoting server together with my web application.

      2) Is possible use java.net.socket to do clients for jboss remoting with socket transport?

      3) Is possible legacy systems connect on jboss remoting servers that use socket transport?

      3) When some changes happening on my web service is possible with jboss remoting send message for all clients?


      Thanks for help.


      Eliezer.

        • 1. Re: JBoss remoting integration with legacy systems
          trustin

          JBoss Remoting uses its own protocol and (at your choice) Java standard object serialization or JBoss Serialization. I don't think non-Java applications can talk to JBoss Remoting services with trivial effort.

          HTH,
          Trustin

          • 2. Re: JBoss remoting integration with legacy systems
            ron_sigal

            Hi Eliezer,

            Trustin has given the answer I always give (thanks, Trustin!), but since this issue has come up recently in a question from our support staff, and since I have put some time into demonstrating that a client using ordinary sockets can talk to a Remoting server using the socket transport, I'm going to elaborate a little bit.

            As Trustin mentioned, the socket transport uses either ObjectOutputStream/ObjectInputStream or JBossObjectOutputStream/JBossObjectInputStream by default, so normally you would have to do the same on the client. Also, the socket transport, since version 2.0.0.GA, has added an extra version byte before each transmission, so you would also have to do that.

            The solution I proposed to the support guys worked around both of these requirements.

            1. The choice of streams is made by the implementations of the org.jboss.remoting.marshal.Marshaller and org.jboss.remoting.marshal.UnMarshaller interfaces, and the default choices for the socket transport (org.jboss.remoting.marshal.serializable.SerializableMarshaller and org.jboss.remoting.marshal.serializable.SerializableUnMarshaller) use object streams. To avoid using object streams, then, you can write and configure your own marshaller and unmarshaller. In my example, I used

            public class IntegrationMarshaller implements Marshaller
            {
             private static final long serialVersionUID = 1L;
            
             public Marshaller cloneMarshaller() throws CloneNotSupportedException
             {
             return new IntegrationMarshaller();
             }
            
             public void write(Object dataObject, OutputStream output) throws IOException
             {
             PrintStream ps = new PrintStream(output);
             if (dataObject instanceof String)
             {
             ps.println((String) dataObject);
             ps.flush();
             }
             else if (dataObject instanceof InvocationRequest && ((InvocationRequest) dataObject).getParameter() instanceof String)
             {
             ps.println(((InvocationRequest) dataObject).getParameter());
             ps.flush();
             }
             else
             {
             throw new IOException("unexpected data type: " + dataObject);
             }
             }
            }
            


            and

            public class IntegrationUnmarshaller implements UnMarshaller
            {
             private static final long serialVersionUID = 1L;
            
             public UnMarshaller cloneUnMarshaller() throws CloneNotSupportedException
             {
             return new IntegrationUnmarshaller();
             }
            
             public Object read(InputStream inputStream, Map metadata) throws IOException, ClassNotFoundException
             {
             BufferedReader br = new BufferedReader(new InputStreamReader(inputStream));
             String s = br.readLine();
             if (s == null)
             {
             throw new EOFException();
             }
             System.out.println(this + " received: " + s);
             return s;
             }
            
             public void setClassLoader(ClassLoader classloader)
             {
             }
            }
            


            Of course, they handle only strings, but that was OK for the example. You might need to do something different.

            Now, to tell Remoting to use these classes, you can use the "marshaller" and "unmarshaller" parameters. For example:

            socket://127.0.0.1:8888/?marshaller=your.package.IntegrationMarshaller&unmarshaller=your.package.IntegrationUnmarshaller
            


            2. You can tell Remoting to eliminate the version byte by telling it to be compatible with the versions that preceded 2.0.0. The way to do this is to set the system property "jboss.remoting.pre_2_0_compatible" to "true". In Remoting 2.4/2.5, you can also set "jboss.remoting.pre_2_0_compatible" to "true" in the InvokerLocator.

            Let us know how is goes.

            -Ron

            • 3. Re: JBoss remoting integration with legacy systems
              tmarks

              Obviously, this is an old post. Is there a better way to implement this using remoting 2.5.3?

              • 4. Re: JBoss remoting integration with legacy systems
                ron_sigal

                Hi Tim,

                 

                Nah, Remoting 2.5 isn't fundamentally different than Remoting 2.2.

                 

                -Ron