Announcement Announcement Module
Collapse
No announcement yet.
RmiServiceExporter / RmiProxyFactoryBean Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • RmiServiceExporter / RmiProxyFactoryBean

    Hy!

    Please HELP! The ServerProg is running but I have still problems with the Client.

    SERVER:
    <beans>
    <bean id="accountService" class="de.sonic.rmi.server02.AccountServiceImpl" />
    <bean class="org.springframework.remoting.rmi.RmiService Exporter">
    <property name="serviceName" value="AccountService"/>
    <property name="service" ref="accountService"/>
    <property name="serviceInterface" value="de.sonic.rmi.server02.AccountService"/>
    <property name="registryHost" value="<real IP 10...>"/>
    <!-- defaults to 1099 -->
    <property name="registryPort" value="1099"/>
    </bean>
    </beans>

    public interface AccountService {
    public void insertAccount(Account acc);
    public List getAccounts(String name); }

    public class AccountServiceImpl implements AccountService {
    List accounts = new ArrayList();
    public void insertAccount(Account acc) {accounts.add(acc);}
    public List getAccounts(String name) {return listOfAccounts;} }

    public class Account implements Serializable {
    private String name;
    public String getName() { return name; };
    public void setName(String name) {this.name = name;}}

    public static void main(String[] args) {

    String codebase = "http://<IP>/rmi/Spring_RMI_Server01_02/";;
    System.setProperty( "java.rmi.server.codebase", codebase );
    System.setProperty( "java.security.policy", codebase+"java.policy" );
    System.setSecurityManager( new RMISecurityManager() );

    try {
    BeanFactory bf = new ClassPathXmlApplicationContext("de/sonic/rmi/server02/asd.xml");
    } catch (BeanCreationException bce) {bce.printStackTrace();}
    catch (Exception e) {e.printStackTrace();}
    }



    CLIENT:
    <bean id="simpleClient" class="de.sonic.rmi.client02.SimpleClient">
    <property name="accountService">
    <ref bean="accountService"/>
    </property>
    </bean>

    <bean id="accountService" class="org.springframework.remoting.rmi.RmiProxyFa ctoryBean">
    <property name="serviceUrl">
    <value>rmi://<IP>:1099/AccountService</value>
    </property>
    <property name="serviceInterface">
    <value>de.sonic.rmi.client02.AccountService</value>
    </property>
    </bean>

    public static void main(String[] args) {
    String codebase = "http://<IP>/rmi/Spring_RMI_Server01_02/";;
    System.setProperty( "java.rmi.server.codebase", codebase );
    System.setProperty( "java.security.policy", codebase+"java.policy" );
    System.setSecurityManager( new RMISecurityManager() );

    BeanFactory bf = new ClassPathXmlApplicationContext("/de/sonic/rmi/client02/client.xml");

    AccountService as = (AccountService)bf.getBean("accountService");
    Account a = new Account();
    a.setName("Sonic");

    try {as.insertAccount(a);
    } catch (Exception e) {e.printStackTrace();}

    }

    public class SimpleClient {
    private AccountService accountService;
    public void setAccountService(AccountService accountService) {
    this.accountService = accountService;
    }

    public void insertNewAccount(Account acc) {
    try {accountService.insertAccount(acc);
    } catch (Exception e) {e.printStackTrace();}
    }

    public List getAccountsByName(String name) {
    return accountService.getAccounts(name);}
    }

    public interface AccountService {
    public void insertAccount(Account acc);
    public List getAccounts(String name);
    }

    public class Account implements Serializable {
    private String name;
    public String getName() { return name; };
    public void setName(String name) {this.name = name;}
    }


    The Server is starting, but the Client throws the following Error:

    java.lang.NoSuchMethodException: $Proxy0.insertAccount(de.sonic.rmi.client02.Accoun t)
    at java.lang.Class.getMethod(Class.java:1581)
    at org.springframework.remoting.support.RemoteInvocat ion.invoke(RemoteInvocation.java:178)
    at org.springframework.remoting.support.DefaultRemote InvocationExecutor.invoke(DefaultRemoteInvocationE xecutor.java:33)
    at org.springframework.remoting.support.RemoteInvocat ionBasedExporter.invoke(RemoteInvocationBasedExpor ter.java:76)
    at org.springframework.remoting.rmi.RmiBasedExporter. invoke(RmiBasedExporter.java:72)
    at org.springframework.remoting.rmi.RmiInvocationWrap per.invoke(RmiInvocationWrapper.java:62)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:585)
    at sun.rmi.server.UnicastServerRef.dispatch(UnicastSe rverRef.java:294)
    at sun.rmi.transport.Transport$1.run(Transport.java:1 53)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.rmi.transport.Transport.serviceCall(Transport. java:149)
    at sun.rmi.transport.tcp.TCPTransport.handleMessages( TCPTransport.java:460)
    at sun.rmi.transport.tcp.TCPTransport$ConnectionHandl er.run(TCPTransport.java:701)
    at java.lang.Thread.run(Thread.java:595)
    at sun.rmi.transport.StreamRemoteCall.exceptionReceiv edFromServer(StreamRemoteCall.java:247)
    at sun.rmi.transport.StreamRemoteCall.executeCall(Str eamRemoteCall.java:223)
    at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:1 26)
    at org.springframework.remoting.rmi.RmiInvocationWrap per_Stub.invoke(Unknown Source)
    at org.springframework.remoting.rmi.RmiClientIntercep tor.doInvoke(RmiClientInterceptor.java:347)
    at org.springframework.remoting.rmi.RmiClientIntercep tor.doInvoke(RmiClientInterceptor.java:294)
    at org.springframework.remoting.rmi.RmiClientIntercep tor.invoke(RmiClientInterceptor.java:209)
    at org.springframework.aop.framework.ReflectiveMethod Invocation.proceed(ReflectiveMethodInvocation.java :170)
    at org.springframework.aop.framework.JdkDynamicAopPro xy.invoke(JdkDynamicAopProxy.java:176)
    at $Proxy0.insertAccount(Unknown Source)
    at de.sonic.rmi.client02.MyRMIClient.main(MyRMIClient .java:41)

    Why is the Programm searching for the Method in Account?
    An Errors in the ConfigFiles? The App without Spring (only RMI) is running. I have to compare the speed of the different implementations. Hessian and HTTPInvoker will be tested later.

    Thanks a lot!
    Sonic

  • #2
    Your setup looks ok. I see you have set the codebase url in the client. Are you actually doing remote code loading?

    If not, are you using the same .class files for Account and the AccountService interface in both processes? From the stack trace it's evident that the server cannot match the method given by the method invocation up with the service implementation. I don't see any other reason from what you've given than a classloader issue.

    Jess

    Comment


    • #3
      Hy!

      First thank you for your reply!!!
      I have 2 Computers. I generate the ServerCode and copy what I need to the second computer to write the Client, so the Account.class is the same. The same Files I copy to the CodeBase. I tried it with and without CodeBase in the Client, but still the same Error. In the WebServers logFile, I can see, that the Progs are getting the java.policy File and the Account.class!

      Still the same ERROR! :-((

      Thank you!
      Sonic

      Comment


      • #4
        Well based on what you have given there shouldn't be a problem. I built and tested this on my workstation without a problem. I have attached a zip file with all the classes and test configurations that I used. You can edit the top of the build.xml and setup your classpath for the Spring jar and try to run this. If you have an additional problem reconciling the differences, let me know.

        Jess

        Comment


        • #5
          Good morning!

          Thank you very much for your help!
          I downloaded the file and will try it out now.
          Thank you!!!

          Comment


          • #6
            Hy!

            Local, on one Computer, itīs working.
            BUT ServerProg on one and the ClientProg on the other Computer, still the same ERROR! :-((
            I think it is for Client Server programming?!?!?!

            Thanks a lot for your help!

            Comment


            • #7
              Itīs working! :-)) It was my mistake!
              Hmmm, shame on me! :-(( What a mistake!
              I did one server test package and one for the Client!
              ->The Account Class is in both packages.
              The server interface method:
              public void insertAccount(de.server.Account acc);

              The client interface Method:
              public void insertAccount(de.client.Account acc);

              It have to be the same Package!!!

              The server interface method:
              public void insertAccount(de.same.package.Account acc);

              The client interface Method:
              public void insertAccount(de.same.package.Account acc);

              Thank you all for the help!!!

              Comment


              • #8
                Originally posted by Sonic
                Itīs working! :-)) It was my mistake!
                Hmmm, shame on me! :-(( What a mistake!
                I did one server test package and one for the Client!
                Hello!
                I'm trying to do the same that you did, but I dont have understood one thing.
                The client side, ok, it can be a classicale webapp, packaged into one war archive. In this war I have my beans definition, client beans, I mean.

                For the server side, I can make a jar archive, with all my classes, and another beans definition file???
                When the server go up, how knows that must load also the beans definition that is in the jar??

                I'm asking this because in the war, I have the web.xml file where I activate te SpringListener that load the beans definition, but in the jar I dont have it.

                I hope you have understood my doubt

                Salud

                Max

                Comment


                • #9
                  Max -

                  You will need to write something to bootstrap the server. Normally this is a simple Java class that loads the application context. There is an example of the 'main' method of this class in the thread. Find this and review it and see if it works for you.

                  Jess

                  Comment


                  • #10
                    Originally posted by jbalint
                    Max -

                    You will need to write something to bootstrap the server. Normally this is a simple Java class that loads the application context. There is an example of the 'main' method of this class in the thread. Find this and review it and see if it works for you.

                    Jess
                    Hi Jess, again me
                    I've found the "main class" you are speaking about but, first of all I see two similar classes, one in the front-end war, and another into the backend jar archive.
                    Both are mandatory?

                    Then I see that these classes more than loading their own applicationContext, execute this code:
                    Code:
                    String codebase = "http://<IP>/rmi/Spring_RMI_Server01_02/";;
                    System.setProperty( "java.rmi.server.codebase", codebase );
                    System.setProperty( "java.security.policy", codebase+"java.policy" );
                    System.setSecurityManager( new RMISecurityManager() );
                    What does this code do?
                    ( Sorry for this silly question, but in RMI I'm just a newby )

                    At last, but of course not the least, I have my jar archive deployed on another machine, on another A.S (BEA Weblogic), when BEA starts up, how my "main" class is executed automatically??? I must execute that class declaring it in my server beans definition deployed on the client??

                    Any help is appreciated

                    Thanks a lot.

                    Max

                    Comment


                    • #11
                      If you are using WebLogic, check out their RMI support http://www.weblogic.com/docs/classdocs/API_rmi.html. This will eliminate the need for a separate JVM (and main method). The other lines of code are used for mobile code which you only need if the interfaces aren't already available to the client.

                      Jess

                      Comment


                      • #12
                        Originally posted by jbalint
                        If you are using WebLogic, check out their RMI support http://www.weblogic.com/docs/classdocs/API_rmi.html. This will eliminate the need for a separate JVM (and main method). The other lines of code are used for mobile code which you only need if the interfaces aren't already available to the client.

                        Jess
                        Hi Jess, we will use BEA in integration environment, and production. For development purposes we choosed to use JBoss, much light
                        So I dont want to use API specific for BEA in my code

                        Salud

                        Max

                        Comment


                        • #13
                          You can use Spring to export your service. You can deploy into the JBoss/WebLogic server using a WAR and the ContextLoaderListener. Then, to export your RMI service, you will need something like this in your application context:

                          Code:
                            <!-- Service implementation implements the MyService interface -->
                            <bean id="myService" class="xx.MyServiceImpl"/>
                          
                            <bean class="org.springframework.remoting.rmi.RmiServiceExporter">
                              <property name="serviceName" value="MyService"/>
                              <!-- Ref to service implementation -->
                              <property name="service" ref="myService"/>
                              <property name="serviceInterface" value="xx.MyService"/>
                            </bean>
                          This will export the service reference into the RMI registry under the name "MyService".

                          Jess

                          Comment


                          • #14
                            Originally posted by jbalint
                            You can use Spring to export your service. You can deploy into the JBoss/WebLogic server using a WAR and the ContextLoaderListener. Then, to export your RMI service, you will need something like this in your application context:

                            Code:
                              <!-- Service implementation implements the MyService interface -->
                              <bean id="myService" class="xx.MyServiceImpl"/>
                            
                              <bean class="org.springframework.remoting.rmi.RmiServiceExporter">
                                <property name="serviceName" value="MyService"/>
                                <!-- Ref to service implementation -->
                                <property name="service" ref="myService"/>
                                <property name="serviceInterface" value="xx.MyService"/>
                              </bean>
                            This will export the service reference into the RMI registry under the name "MyService".

                            Jess
                            sorry Jess, but I keep not understanding.
                            I tell what I did up to now.

                            One war deployed into JBoss into one machine. In this war I have my applicationContext with the client beans definition, and this one also:

                            Code:
                            <bean id="profilingService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
                            	<property name="serviceUrl">
                            		<value>rmi://localhost:1099/ProfilingService</value>
                            	</property>
                            	<property name="serviceInterface">
                            		<value>ProfilingService</value>
                            	</property>
                            </bean>

                            In my JBoss ( or BEA ) that acts as server, deployed into another computer, I have one simple jar, with my services beans.
                            I must put another applicationContext in this jar on the server?
                            If yes I can define into it my serverside beans definition, and also this one:
                            Code:
                            <bean class="org.springframework.remoting.rmi.RmiServiceExporter">
                            	<!-- does not necessarily have to be the same name as the bean to be exported -->
                            	<property name="serviceName"><value>ProfilingService</value></property>
                            	<property name="service"><ref bean="profilingManager"/></property>
                            	<property name="serviceInterface"><value>web.profiling.services.ProfilingService</value></property>
                            	<!-- defaults to 1099 -->
                            	<property name="registryPort"><value>1099</value></property>
                            </bean>
                            I also put into the server jar a class with a main method, that, when executed, tells programmatically to Spring to load server side beans definition.
                            Right?

                            The problem is, How I tell to JBoss ( or BEA ) to execute that main class, being that I'm not in a war but into a simple jar???

                            I hope to have well explained my situation.

                            salud

                            Max

                            Comment


                            • #15
                              The main() method is not applicable when running inside the application server. You need to deploy a war or ear in the application server. In your web.xml in the war, you should use the ContextLoaderListener so it loads your application context and exports the RMI service.

                              Jess

                              Comment

                              Working...
                              X