Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Wie kann mit Java und CORBA der Ausfall des Servers abgefangen werden ?
Ich schreibe zwei Praktikumsaufgaben mit Java und CORBA und habe das Problem, daß unser Professor totale Fehlertoleranz auch bei Absturz des jeweiligen Servers fordert. Viele der CORBA-Exceptions können mit try-catch und Throwable abgefangen werden, aber bei Ausfall des Servers bricht CORBA von sich aus ab.
Weder der Professor noch der Assistent haben hierzu die Lösung angegeben (der Assistent weiß es anscheinend selber nicht) und es wissen auch viele der anderen Studenten nicht, wie es geht. Jetzt sind Semesterferien, sodaß ich an die anderen Studenten nicht mehr herankomme.
Weiß einer von euch, wie der jeweilige Server (je nach IDL-Methode) angesprochen werden kann, ohne daß CORBA das Programm eigenmächtig abbricht ? ("Oneway" ist nicht geeignet):noe:
So richtig verstehe ich die Frage nicht, weil ich die Architektur nicht verstehe. Welcher Teil soll überleben, wenn welcher Teil stirbt? Und was soll dann genau passieren?
CORBA ist ein Framework für verteilte Anwendungen, das möglichst viele Programmiersprachen unterstützt - innerhalb einer Programmiersprache und auch unter mehreren Programmiersprachen untereinander: Client-Server-Anwendungen sind damit komplett in Java möglich, genauso ist es aber auch möglich, einen Client in Java zu schreiben, einen weiteren Client in C++ und den Server wieder in Java.
Hierzu wird die Schnittstelle/das Interface angegeben in der IDL=Interface Definition Language: hier hinein schreibt man quasi das Java-Interface, das der Server dann implementieren muß. So kann jeder Rechner Client und eben auch Server sein.
Es gibt in CORBA viele Exceptions, die auch alle erfolgreich abgefangen werden können mit try-catch. Leider ist mir nicht bekannt, wie man die Anfrage eines Clients an einen abgeschalteten Server abfangen kann: CORBA scheint hier ein System.exit auszuführen. Trotzdem war es während des Semesters mehrmals im Gespräch, daß der Client auch trotz eines abgeschalteten Servers weiterarbeiten kann und es wird so in der Aufgabenstellung verlangt: es gibt in der Aufgabenstellung drei Server, von denen bis zu zwei durch Abschalten ausfallen dürfen und die nach dem Wiedereinschalten fragen sollen, wie denn der Stand der Dinge ist, um, als wäre nichts passiert, wieder ganz normal weiterzuarbeiten (das nennt sich Fehlertoleranz).
Das beigefüge Java-Projekt wird folgendermaßen gestartet:
1. Den CORBA-Dienst (CORBA-Dämon) starten: DOS-Promptrbd -ORBInitialHost localhost -ORBInitialPort 20000
2. Die IDL kompilieren (ist im beigefügten Projekt bereits gemacht, aber kann man ja trotzdem noch einmal schreiben): DOS-Prompt: in das Verzeichnis der Datei "aufgabe2.idl" wechseln, "idlj -fall aufgabe2.idl"
3. Den Server starten: DOS-Prompt: in das "bin/"-Verzeichnis des Projekts wechseln (ist ja seit Eclipse 3.3 sehr wichtig), "java pack1/Programm1 -ORBInitialHost localhost -ORBInitialPort 20000"
4. Den Client starten: DOS-Prompt: in das "bin/"-Verzeichnis wechseln, "java pack1/Programm2 -ORBInitialHost localhost -ORBInitialPort 20000"
Wer mit Eclipse umgehen kann, kann die Argumente auch als Parameter eingeben. Eclipse läuft pro Arbeitsbereich aber nur mit einer Instanz von Eclipse. Um Client und Server nebeneinander programmieren zu können, könnte man auch den Server mit Eclipse und den Client mit NetBeans programmieren, aber das ist alles sehr kompliziert. Deswegen sind wir im Praktikum dabei geblieben, die Auto-Build-Funktion von Eclipse zu benutzen und ansonsten alles mit DOS-Prompts zu starten.
Wenn die Punkte 1 bis 4 richtig beachtet wurden, erscheint auf dem Server die Ausgabe "Text=Hallo";
wenn der Server nicht läuft (wenn Punkt 3 ausgelassen wird), kommt auf dem Client eine ellenlange Fehlermeldung, die sich nicht ausschalten läßt, auch nicht mit Throwable, der größten aller Exceptions, und der Client bricht ab.
Trotzdem ist es möglich, daß der Client nach dem Aufruf eines abgeschalteten Servers normal weiterlaufen kann. Und genau das ist meine Frage. Das Attribut "oneway" in der IDL habe ich bereits probiert: klappt auch nicht.
Was muß man machen, damit der Client den Absturz des Servers zwar mitbekommt, aber davon nicht völlig aus der Bahn geworfen wird ?
Mit meiner Frage oben meinte ich nicht, dass ich CORBA nicht kenne, oder nicht weiß was ein ORB ist. Ich wusste aber nicht, wie das Programm aufgeteilt ist.
Es geht also darum, dass ein Client nicht sterben darf, nur weil sein Server nicht erreichbar ist, bzw. während einer Anfrage verstirbt. Muss er auch einen Ausfahl des ORB überleben, oder gilt dieser als hochverfügbar?
Dann hätte ich doch gern mal die ellenlange Fehlermeldung gesehen. Und natürlich das Stück Quelltext das die Anfrage zum Server aufbaut.
Die Fehlermeldung lautet:
A
B
17.07.2009 19:37:37 com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl <init>
WARNUNG: "IOP00410201: (COMM_FAILURE) Connection failure: socketType: IIOP_CLEAR_TEXT; hostname: 169.254.213.216; port: 2041"
org.omg.CORBA.COMM_FAILURE: vmcid: SUN minor code: 201 completed: No
at com.sun.corba.se.impl.logging.ORBUtilSystemException.connectFailure(Unknown Source)
at com.sun.corba.se.impl.logging.ORBUtilSystemException.connectFailure(Unknown Source)
at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.<init>(Unknown Source)
at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.<init>(Unknown Source)
at com.sun.corba.se.impl.transport.SocketOrChannelContactInfoImpl.createConnection(Unknown Source)
at com.sun.corba.se.impl.protocol.CorbaClientRequestDispatcherImpl.beginRequest(Unknown Source)
at com.sun.corba.se.impl.protocol.CorbaClientDelegateImpl.request(Unknown Source)
at org.omg.CORBA.portable.ObjectImpl._request(Unknown Source)
at aufgabe2._NeuStub.nachricht(_NeuStub.java:18)
at pack1.Programm2.main(Programm2.java:52)
Caused by: java.net.ConnectException: Connection refused: connect
at sun.nio.ch.Net.connect(Native Method)
at sun.nio.ch.SocketChannelImpl.connect(Unknown Source)
at java.nio.channels.SocketChannel.open(Unknown Source)
at com.sun.corba.se.impl.transport.DefaultSocketFactoryImpl.createSocket(Unknown Source)
... 8 more
org.omg.CORBA.COMM_FAILURE: vmcid: SUN minor code: 201 completed: No
at com.sun.corba.se.impl.logging.ORBUtilSystemException.connectFailure(Unknown Source)
at com.sun.corba.se.impl.logging.ORBUtilSystemException.connectFailure(Unknown Source)
at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.<init>(Unknown Source)
at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.<init>(Unknown Source)
at com.sun.corba.se.impl.transport.SocketOrChannelContactInfoImpl.createConnection(Unknown Source)----------------- COMM-FAILURE
at com.sun.corba.se.impl.protocol.CorbaClientRequestDispatcherImpl.beginRequest(Unknown Source)
at com.sun.corba.se.impl.protocol.CorbaClientDelegateImpl.request(Unknown Source)
at org.omg.CORBA.portable.ObjectImpl._request(Unknown Source)
at aufgabe2._NeuStub.nachricht(_NeuStub.java:18)
at pack1.Programm2.main(Programm2.java:52)
Caused by: java.net.ConnectException: Connection refused: connect
at sun.nio.ch.Net.connect(Native Method)
at sun.nio.ch.SocketChannelImpl.connect(Unknown Source)
at java.nio.channels.SocketChannel.open(Unknown Source)
at com.sun.corba.se.impl.transport.DefaultSocketFactoryImpl.createSocket(Unknown Source)
... 8 more
Das Stück Quelltext des Clients, das diese Fehlermeldung verursacht hat, lautet:
Java:
package pack1;
import aufgabe2.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;
import java.io.*;
import java.rmi.ConnectException;
import java.net.*;
public class Programm2
{
static Neu neu1;
static Thread[] thread1=new Thread[10];
public static void main(String args[])
{
int i;
try
{
String[] arg=new String[]{"-ORBInitialHost","localhost",
"-ORBInitialPort","20000"};
// create and initialize the ORB
ORB orb = ORB.init(arg, null);
// get reference to rootpoa & activate the POAManager
POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
rootpoa.the_POAManager().activate();
// get the root naming context
org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
// Use NamingContextExt instead of NamingContext. This is
// part of the Interoperable naming Service.
NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
System.out.println("A");
// resolve the Object Reference in Naming
String kname = "Neu1";
neu1 = NeuHelper.narrow(ncRef.resolve_str(kname));
System.out.println("B");
neu1.nachricht("Hallo");
System.out.println("C");
System.out.println("Client ist fertig ...");
// wait for invocations from clients
orb.run();
}
catch(COMM_FAILURE e)
{
System.out.println("----------------- COMM-FAILURE");
e.printStackTrace();
}
catch(OBJECT_NOT_EXIST e)
{
System.out.println("--------------------- Throwable");
e.printStackTrace();
}
catch(NO_PERMISSION e)
{
System.out.println("--------------------- Throwable");
e.printStackTrace();
}
catch(org.omg.CORBA.SystemException e)
{
System.out.println("---------------------- Eigene System-Exception");
e.printStackTrace();
}
catch (Exception e)
{
System.out.println("-------------------------------- Eigene Fehlermeldung");
System.out.println("ERROR : " + e) ;
e.printStackTrace(System.out);
}
catch(Throwable e)
{
System.out.println("--------------------- Throwable");
e.printStackTrace();
}
}
}
Schnickschnack, da ist doch Deine Ausgabe [c]----------------- COMM-FAILURE[/c]. Die ist halt mittendrin, weil stderr und stdout nicht gegeneinander synchronisiert sind. Die Anwendung beendet sich, weil die [c]main()[/c]-Methode nach dem catch-Block verlassen wird. Mach eine Endlosschleife um den gesamten [c]main()[/c]-Methodenrumpf und Du wirst sehen, dass die Anwendung nicht terminiert.
Es bleibt allerdings das (kleine) Problem, daß CORBA eigene Fehlerausgaben zu machen scheint (falls du dafür auch noch etwas findest): Fehlermeldung jetzt (mit while-Schleife):
Weiterer Durchlauf
17.07.2009 20:18:44 com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl <init>
WARNUNG: "IOP00410201: (COMM_FAILURE) Connection failure: socketType: IIOP_CLEAR_TEXT; hostname: 169.254.213.216; port: 900"
org.omg.CORBA.COMM_FAILURE: vmcid: SUN minor code: 201 completed: No
at com.sun.corba.se.impl.logging.ORBUtilSystemException.connectFailure(Unknown Source)
at com.sun.corba.se.impl.logging.ORBUtilSystemException.connectFailure(Unknown Source)
at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.<init>(Unknown Source)
at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.<init>(Unknown Source)
at com.sun.corba.se.impl.transport.SocketOrChannelContactInfoImpl.createConnection(Unknown Source)
at com.sun.corba.se.impl.protocol.CorbaClientRequestDispatcherImpl.beginRequest(Unknown Source)
at com.sun.corba.se.impl.protocol.CorbaClientDelegateImpl.request(Unknown Source)
at com.sun.corba.se.impl.resolver.BootstrapResolverImpl.invoke(Unknown Source)
at com.sun.corba.se.impl.resolver.BootstrapResolverImpl.resolve(Unknown Source)
at com.sun.corba.se.impl.resolver.CompositeResolverImpl.resolve(Unknown Source)
at com.sun.corba.se.impl.resolver.CompositeResolverImpl.resolve(Unknown Source)
at com.sun.corba.se.impl.resolver.CompositeResolverImpl.resolve(Unknown Source)
at com.sun.corba.se.impl.orb.ORBImpl.resolve_initial_references(Unknown Source)
at pack1.Programm2.main(Programm2.java:42)
Caused by: java.net.ConnectException: Connection refused: connect
at sun.nio.ch.Net.connect(Native Method)
at sun.nio.ch.SocketChannelImpl.connect(Unknown Source)
at java.nio.channels.SocketChannel.open(Unknown Source)
at com.sun.corba.se.impl.transport.DefaultSocketFactoryImpl.createSocket(Unknown Source)
... 12 more
----------------- COMM-FAILURE
Weiterer Durchlauf
17.07.2009 20:18:45 com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl <init>
WARNUNG: "IOP00410201: (COMM_FAILURE) Connection failure: socketType: IIOP_CLEAR_TEXT; hostname: 169.254.213.216; port: 900"
org.omg.CORBA.COMM_FAILURE: vmcid: SUN minor code: 201 completed: No
at com.sun.corba.se.impl.logging.ORBUtilSystemException.connectFailure(Unknown Source)
at com.sun.corba.se.impl.logging.ORBUtilSystemException.connectFailure(Unknown Source)
at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.<init>(Unknown Source)
at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.<init>(Unknown Source)
at com.sun.corba.se.impl.transport.SocketOrChannelContactInfoImpl.createConnection(Unknown Source)
at com.sun.corba.se.impl.protocol.CorbaClientRequestDispatcherImpl.beginRequest(Unknown Source)
at com.sun.corba.se.impl.protocol.CorbaClientDelegateImpl.request(Unknown Source)
at com.sun.corba.se.impl.resolver.BootstrapResolverImpl.invoke(Unknown Source)
at com.sun.corba.se.impl.resolver.BootstrapResolverImpl.resolve(Unknown Source)
at com.sun.corba.se.impl.resolver.CompositeResolverImpl.resolve(Unknown Source)
at com.sun.corba.se.impl.resolver.CompositeResolverImpl.resolve(Unknown Source)
at com.sun.corba.se.impl.resolver.CompositeResolverImpl.resolve(Unknown Source)
at com.sun.corba.se.impl.orb.ORBImpl.resolve_initial_references(Unknown Source)
at pack1.Programm2.main(Programm2.java:42)
Caused by: java.net.ConnectException: Connection refused: connect
at sun.nio.ch.Net.connect(Native Method)
at sun.nio.ch.SocketChannelImpl.connect(Unknown Source)
at java.nio.channels.SocketChannel.open(Unknown Source)
at com.sun.corba.se.impl.transport.DefaultSocketFactoryImpl.createSocket(Unknown Source)
... 12 more
----------------- COMM-FAILURE
Weiterer Durchlauf
17.07.2009 20:18:46 com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl <init>
WARNUNG: "IOP00410201: (COMM_FAILURE) Connection failure: socketType: IIOP_CLEAR_TEXT; hostname: 169.254.213.216; port: 900"
org.omg.CORBA.COMM_FAILURE: vmcid: SUN minor code: 201 completed: No
at com.sun.corba.se.impl.logging.ORBUtilSystemException.connectFailure(Unknown Source)
at com.sun.corba.se.impl.logging.ORBUtilSystemException.connectFailure(Unknown Source)
at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.<init>(Unknown Source)
at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.<init>(Unknown Source)
at com.sun.corba.se.impl.transport.SocketOrChannelContactInfoImpl.createConnection(Unknown Source)
at com.sun.corba.se.impl.protocol.CorbaClientRequestDispatcherImpl.beginRequest(Unknown Source)
at com.sun.corba.se.impl.protocol.CorbaClientDelegateImpl.request(Unknown Source)
at com.sun.corba.se.impl.resolver.BootstrapResolverImpl.invoke(Unknown Source)
at com.sun.corba.se.impl.resolver.BootstrapResolverImpl.resolve(Unknown Source)
at com.sun.corba.se.impl.resolver.CompositeResolverImpl.resolve(Unknown Source)
at com.sun.corba.se.impl.resolver.CompositeResolverImpl.resolve(Unknown Source)
at com.sun.corba.se.impl.resolver.CompositeResolverImpl.resolve(Unknown Source)
at com.sun.corba.se.impl.orb.ORBImpl.resolve_initial_references(Unknown Source)
at pack1.Programm2.main(Programm2.java:42)
Caused by: java.net.ConnectException: Connection refused: connect
at sun.nio.ch.Net.connect(Native Method)
at sun.nio.ch.SocketChannelImpl.connect(Unknown Source)
at java.nio.channels.SocketChannel.open(Unknown Source)
at com.sun.corba.se.impl.transport.DefaultSocketFactoryImpl.createSocket(Unknown Source)
... 12 more
----------------- COMM-FAILURE
Weiterer Durchlauf
17.07.2009 20:18:47 com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl <init>
WARNUNG: "IOP00410201: (COMM_FAILURE) Connection failure: socketType: IIOP_CLEAR_TEXT; hostname: 169.254.213.216; port: 900"
org.omg.CORBA.COMM_FAILURE: vmcid: SUN minor code: 201 completed: No
at com.sun.corba.se.impl.logging.ORBUtilSystemException.connectFailure(Unknown Source)
at com.sun.corba.se.impl.logging.ORBUtilSystemException.connectFailure(Unknown Source)
at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.<init>(Unknown Source)
at com.sun.corba.se.impl.transport.SocketOrChannelConnectionImpl.<init>(Unknown Source)
at com.sun.corba.se.impl.transport.SocketOrChannelContactInfoImpl.createConnection(Unknown Source)
at com.sun.corba.se.impl.protocol.CorbaClientRequestDispatcherImpl.beginRequest(Unknown Source)
at com.sun.corba.se.impl.protocol.CorbaClientDelegateImpl.request(Unknown Source)
at com.sun.corba.se.impl.resolver.BootstrapResolverImpl.invoke(Unknown Source)
at com.sun.corba.se.impl.resolver.BootstrapResolverImpl.resolve(Unknown Source)
at com.sun.corba.se.impl.resolver.CompositeResolverImpl.resolve(Unknown Source)
at com.sun.corba.se.impl.resolver.CompositeResolverImpl.resolve(Unknown Source)
at com.sun.corba.se.impl.resolver.CompositeResolverImpl.resolve(Unknown Source)
at com.sun.corba.se.impl.orb.ORBImpl.resolve_initial_references(Unknown Source)
at pack1.Programm2.main(Programm2.java:42)
Caused by: java.net.ConnectException: Connection refused: connect
at sun.nio.ch.Net.connect(Native Method)
at sun.nio.ch.SocketChannelImpl.connect(Unknown Source)
at java.nio.channels.SocketChannel.open(Unknown Source)
at com.sun.corba.se.impl.transport.DefaultSocketFactoryImpl.createSocket(Unknown Source)
... 12 more
----------------- COMM-FAILURE
Weiterer Durchlauf
bei folgendem Client-Programm:
Java:
package pack1;
import aufgabe2.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
import org.omg.PortableServer.POA;
import org.omg.PortableServer.POAHelper;
import java.io.*;
import java.rmi.ConnectException;
import java.net.*;
public class Programm2
{
static Neu neu1;
static Thread[] thread1=new Thread[10];
public static void main(String args[])
{
int i;
while(true)
{
System.out.println("Weiterer Durchlauf");
try
{
String[] arg=new String[]{"-ORBInitialHost","localhost",
"-ORBInitialPort","20000"};
// create and initialize the ORB
ORB orb = ORB.init(args, null);
// get reference to rootpoa & activate the POAManager
POA rootpoa = POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
rootpoa.the_POAManager().activate();
// get the root naming context
org.omg.CORBA.Object objRef = orb.resolve_initial_references("NameService");
// Use NamingContextExt instead of NamingContext. This is
// part of the Interoperable naming Service.
NamingContextExt ncRef = NamingContextExtHelper.narrow(objRef);
System.out.println("A");
// resolve the Object Reference in Naming
String kname = "Neu1";
neu1 = NeuHelper.narrow(ncRef.resolve_str(kname));
System.out.println("B");
neu1.nachricht("Hallo");
System.out.println("C");
System.out.println("Client ist fertig ...");
// wait for invocations from clients
// orb.run();
}
catch(COMM_FAILURE e)
{
System.out.println("----------------- COMM-FAILURE");
// e.printStackTrace();
}
catch(OBJECT_NOT_EXIST e)
{
System.out.println("--------------------- Throwable");
// e.printStackTrace();
}
catch(NO_PERMISSION e)
{
System.out.println("--------------------- Throwable");
// e.printStackTrace();
}
catch(org.omg.CORBA.SystemException e)
{
System.out.println("---------------------- Eigene System-Exception");
// e.printStackTrace();
}
catch (Exception e)
{
System.out.println("-------------------------------- Eigene Fehlermeldung");
// System.out.println("ERROR : " + e) ;
// e.printStackTrace(System.out);
}
catch(Throwable e)
{
System.out.println("--------------------- Throwable");
// e.printStackTrace();
}
}
}
}
Ist nicht einfach.
Man könnte mit setLevel bestimmte Meldungen unterdrücken, aber dafür bräuchte man den Namen des Loggers. Mit getLoggerNames bekommt man nur den Namen "global", setLevel(Level.OFF) auf diesen Logger angewendet bringt keine Veränderung.
Man bräuchte den Namen des CORBA-Loggers, aber der läßt sich nicht so schnell finden. Noch 'ne Idee ?
Der Name sollte [c]com.sun.corba.se.impl.transport.SocketOrChannelCon[/c] lauten. Du kannst auch gleich Einstellungen für [c]com.sun.corba.se[/c] setzen. Am besten konfiguriert man das Logging durch ein Properties-File. Formatbeschreibung findest Du in der API-Doc der LogManager-Klasse. Eine Beispieldatei findet sich irgendwo in diesem README. Du findest vielleicht noch bessere Beispiele. Geladen werden die Properties dann entweder über ein System-Property [c]java.util.logging.config.file[/c] oder per API LogManager.readConfiguration.
PS: Wenn der Logger-Name nicht stimmt, konfigurier Dir mal temporär den XML-Formatter an den ConsoleHandler (statt SimpleFormatter); dann zeigt Dir das Log mit an, wie der Logger heißt.