# Java XML-RPC Server - PHP XML-RPC Client ?



## mediaOne (6. Jul 2007)

Hallo @ll...

Ich versuche nun seid einigen Tagen schon einen Java XML-RPC Server zu bauen, mittels der Apache XML-RPC Dokumentation. Und dazu einen PHP XML-RPC CLient. Um daten vom Client an den Java Server weiter zu geben, der diese dann verarbeitet und einen Status zurück gibt.

Im Moment habe ich folgenden Java Code zusammen:

```
import java.util.*;
import org.apache.xmlrpc.server.*;
import org.apache.xmlrpc.webserver.WebServer;

/**
 *
 * @author mediaOne
 */
public class linuxSIArea {
    linuxSIArea t;

    private final int port = 8200;
    /*private final String propertyFile = "server.properties";*/

    public static void main(String args[]) throws ClassNotFoundException {
        System.out.println("Section: main ");
        try {
            linuxSIArea t = new linuxSIArea();
        } catch (java.io.IOException e) {
            System.out.println("Caught IOException\n");
            e.printStackTrace();
        } catch (org.apache.xmlrpc.XmlRpcException e) {
            System.out.println("Caught IOException\n");
            e.printStackTrace();
        }
    }
    public linuxSIArea() throws java.io.IOException, org.apache.xmlrpc.XmlRpcException, ClassNotFoundException {
        PropertyHandlerMapping mapping = new PropertyHandlerMapping();
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        /*mapping.load(cl, propertyFile);*/
        
        mapping.addHandler("calculate", "linuxSIArea"));
        
        WebServer ws = new WebServer(port);
        XmlRpcServerConfigImpl config = new XmlRpcServerConfigImpl();
        XmlRpcServer server = ws.getXmlRpcServer();
        server.setConfig(config);
        server.setHandlerMapping(mapping);
        System.out.println("test Server wird gestartet...");
        System.out.println("test Server nutzt System Port " + port);
        System.out.println("test Server wartet nun auf anfragen.");
        ws.start();
    }
    
    public String calculate(String n1, String n2){
        int ans = Integer.parseInt(n1)+Integer.parseInt(n2);
        return String.valueOf(ans);
    }

}
```

So in diesem Server bekomme ich die Fehlermeldung das er die Kasse linuxSIArea nicht finden kann. Also fehler wird verursacht bei mapping.addHandler("calculate", "linuxSIArea")); dort gebe ich ja die Function frei in der Klasse damit der PHP Client Sie ansteuern kann. Wo Liegt da der Fehler ?

So nun benötige ich natürlich noch den PHP Client .
Kann mir einer mal zeigen bzw ein beispiel erstellen um diesen zu bauen ?
Alle beispiele die ich nun als PHP Client gefunden habe steuern auch einen PHP Server an.
Also folglich steht als Server Verbindung eine PHP Datei am ende. Nur bei Java habe ich ja keine PHP datei sondern nur eine IP mit Port die ich ansteuern kann.

Brauche da dringendst Hilfe!

Danke


----------



## Murray (6. Jul 2007)

Diese Zeile

```
mapping.addHandler("calculate", "linuxSIArea"));
```
passt doch nicht, oder? Am Ende ist eine Klammer zuviel, und eigentlich erwartet die Methode laut Doku als zweiten Parameter eine Klasse und keinen String.

Versuch mal

```
mapping.addHandler("calculate", linuxSIArea.class);
```

Wenn dann beim Übersetzen noch Fehler auftauchen, poste doch bitte den neuen Code und die Fehlermeldung.


Was das Problem mit dem Client ist, leuchtet mir nicht so recht ein: ein XML-RPC-Client muss doch - egal in welcher Sprache er und der Server implementiert sind - immer eine URL angehen.


----------



## Guest (6. Jul 2007)

Danke, das hat schon mal geholfen und der Server Startet !

Ja das mit dem Client habe ich schon verstanden, weiß nur nicht wie ich ihn umsetzten soll, kannst mir zu meinem Server vielleicht eine Beispiel erstellen ? Muss nicht groß sein.

Nur damit ich es sehen kann und lernen kann!

Danke


----------



## mediaOne (6. Jul 2007)

Ach eine frage habe ich noch,
wie man sieht habe ich den code bereich 

```
/*mapping.load(cl, propertyFile);*/
```

Ausgeklamert weil dieser fehler Liefert !
Weiß nur nicht wieso.

Fehler Meldung:


> symbol  : variable propertyFile
> location: class linuxsi.linuxSIArea
> mapping.load(cl, propertyFile);
> 1 error



Ich weiß das ich da normal angaben machen muss frage mich nur was oder kann ich das ganz weglassen ?


----------



## mediaOne (6. Jul 2007)

Habe doch eine Fehlermeldung!
Also unter Windows geht der Server ohne probleme.
Unter Linux bekomme ich die fehlermeldung:



> CPX104 linuxSIv1 # java -jar linuxSI.jar
> Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/xmlrpc/XmlRpcException



???


----------



## Murray (6. Jul 2007)

mediaOne hat gesagt.:
			
		

> Ach eine frage habe ich noch,
> wie man sieht habe ich den code bereich
> 
> ```
> ...



Das kannst du m.E. weglassen, da du die Handler-Definition ja direkt im Code macht; man kann das alternativ aus einer Datei lesen.


----------



## Murray (6. Jul 2007)

mediaOne hat gesagt.:
			
		

> Habe doch eine Fehlermeldung!
> Also unter Windows geht der Server ohne probleme.
> Unter Linux bekomme ich die fehlermeldung:
> 
> ...



Offensichtlich ein Classpath-Problem. Sind die Apache-Klassen mit in deinem Jar enthalten? Wir sieht das Manifest aus?


----------



## mediaOne (7. Jul 2007)

Hallo...

So nun habe ich es hin bekommen...
Bis auf das Problem das ich nun immer die Fehler Meldung bekomme wenn ich mit dem PHP Client auf den Server zugreife!



> CPX104 linuxSIv1 # java -jar linuxSI.jar
> Jul 7, 2007 1:00:01 AM org.apache.xmlrpc.server.XmlRpcStreamServer execute
> SEVERE: execute: Error while performing request
> java.net.BindException: Address already in use
> ...



Mein Aktueller Java Server Code ist !


```
/*
 * linuxSIArea.java
 * 
 * Created on 06.07.2007, 13:49:59
 * 
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package linuxsi;

import java.util.*;

import org.apache.xmlrpc.server.*;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.webserver.WebServer;

/**
 *
 * @author mstruth
 */
public class linuxSIArea {
    linuxSIArea t;
    private final int port = 8300;
    
    public static void main(String args[])  throws ClassNotFoundException {
    
        try {
            linuxSIArea t = new linuxSIArea();
        } catch (java.io.IOException e) {
            System.out.println("Caught IOException\n");
            e.printStackTrace();
        } catch (org.apache.xmlrpc.XmlRpcException e) {
            System.out.println("Caught IOException\n");
            e.printStackTrace();
        }
        
    }
    
    public linuxSIArea() throws java.io.IOException, org.apache.xmlrpc.XmlRpcException, ClassNotFoundException {
          
        WebServer webServer = new WebServer(port);
          XmlRpcServer xmlRpcServer = webServer.getXmlRpcServer();
        
          PropertyHandlerMapping phm = new PropertyHandlerMapping();
          /* Load handler definitions from a property file.
           * The property file might look like:
           *   Calculator=org.apache.xmlrpc.demo.Calculator
           *   org.apache.xmlrpc.demo.proxy.Adder=org.apache.xmlrpc.demo.proxy.AdderImpl
           */

          phm.load(Thread.currentThread().getContextClassLoader(), "linuxsi/server.properties");

          /* You may also provide the handler classes directly,
           * like this:
           * phm.addHandler("Calculator",
           *     org.apache.xmlrpc.demo.Calculator.class);
           * phm.addHandler(org.apache.xmlrpc.demo.proxy.Adder.class.getName(),
           *     org.apache.xmlrpc.demo.proxy.AdderImpl.class);
           */
          phm.addHandler("calculate", linuxsi.linuxSIArea.class);
          xmlRpcServer.setHandlerMapping(phm);
        
          XmlRpcServerConfigImpl serverConfig = (XmlRpcServerConfigImpl) xmlRpcServer.getConfig();
          serverConfig.setEnabledForExtensions(true);
          serverConfig.setContentLengthOptional(false);

          webServer.start();
      }
      
    public String calculate(){
        String text = "Server Respons";
        return text;
    }

}
```

Wo liegt der Fehler?


----------



## Murray (7. Jul 2007)

Das problem besteht darin, dass bei einem Request eine neue Instanz der Handler-Klasse erzeugt wird. Da bei dir Server und Handler die gleiche Klasse sind und bereits im Default-Konstruktor der Web-Service erzeugt wird, wird beim Request ein neuer Web-Service erzeugt, was nicht klappt, weil der Port natürlich schon belegt ist.

Als schnelle Lösung könntest du unterschiedliche Konstruktoren definieren:


```
/*
* linuxSIArea.java
*
* Created on 06.07.2007, 13:49:59
*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package linuxsi;

import java.util.*;

import org.apache.xmlrpc.server.*;
import org.apache.xmlrpc.XmlRpcException;
import org.apache.xmlrpc.webserver.WebServer;

/**
*
* @author mstruth
*/
public class linuxSIArea {
    linuxSIArea t;
   
    public static void main(String args[])  throws ClassNotFoundException {
   
        try {
            linuxSIArea t = new linuxSIArea( 8300);
        } catch (java.io.IOException e) {
            System.out.println("Caught IOException\n");
            e.printStackTrace();
        } catch (org.apache.xmlrpc.XmlRpcException e) {
            System.out.println("Caught IOException\n");
            e.printStackTrace();
        }
       
    }

    /*
       Default-Konstruktor (für Handler-Instanziierung)
    */
    public linuxSIArea() throws java.io.IOException, org.apache.xmlrpc.XmlRpcException, ClassNotFoundException {
    }
   
    /*
        Service-Konstruktor
    */
    public linuxSIArea( int port) throws java.io.IOException, org.apache.xmlrpc.XmlRpcException, ClassNotFoundException {
         
        WebServer webServer = new WebServer(port);
          XmlRpcServer xmlRpcServer = webServer.getXmlRpcServer();
       
          PropertyHandlerMapping phm = new PropertyHandlerMapping();
          /* Load handler definitions from a property file.
           * The property file might look like:
           *   Calculator=org.apache.xmlrpc.demo.Calculator
           *   org.apache.xmlrpc.demo.proxy.Adder=org.apache.xmlrpc.demo.proxy.AdderImpl
           */

          phm.load(Thread.currentThread().getContextClassLoader(), "linuxsi/server.properties");

          /* You may also provide the handler classes directly,
           * like this:
           * phm.addHandler("Calculator",
           *     org.apache.xmlrpc.demo.Calculator.class);
           * phm.addHandler(org.apache.xmlrpc.demo.proxy.Adder.class.getName(),
           *     org.apache.xmlrpc.demo.proxy.AdderImpl.class);
           */
          phm.addHandler("calculate", linuxsi.linuxSIArea.class);
          xmlRpcServer.setHandlerMapping(phm);
       
          XmlRpcServerConfigImpl serverConfig = (XmlRpcServerConfigImpl) xmlRpcServer.getConfig();
          serverConfig.setEnabledForExtensions(true);
          serverConfig.setContentLengthOptional(false);

          webServer.start();
      }
     
    public String calculate(){
        String text = "Server Respons";
        return text;
    }

}
```

Alternativ könntest du den Handler auch in einer eigenen Klasse implementieren.


----------

