Abbruch von Subthreads erzwingen

X

xoom4

Hi

Ich muss auf eine externe API zugreiffen, genauer gesagt auf die JForex API. Dort gibts ein Interface genannt IClient die mittels ClientFactory.getDefaultInstance() instanziert wird. Danach verbindet man sich mit der IClient Interface zum server mit der connect() Methode. Das ganze ist also erstmals unspektakulär und warscheinlich den meisten bekannt.

Doch was dem IClient Interface fehlt ist eine disconnect Methode :eek: Man muss also die gesammte Java Application mit gewalt, also Ctrl + C beenden sonst bleibt der Prozess hängen wenn man die Applikation beenden will. Meines wissens sind einige Subthreads des IClient Interfaces wie Sockets für die Verbindung noch aktiv auch wenn ich System.exit aufrufe. Weil ich also keine möglichkeit habe diese Subthreads mit einer disconnect Methode oder System.exit zu schliessen, fragt sich mich was es noch für alternativen gäbe.

Den Prozess selbst zu schliessen währe mit Betriebsystem nativen Methoden bestimmt möglich, aber unschön zumal für jedes OS eine separierte Lösung gebaut werden muss. Kann man das irgendwie doch noch mit einem OS unabhängige Ansatz realisieren?
 
Öhm ... das würde ich als Bug beim Entwickler einreichen und auf einen Fix warten da das gewaltsame killen eine Threads von außen in Java nicht garantiert wird.
 
Naja, die Alternative wäre sich mit der ThreadGroup alle Threads zu suchen und dann über Stop() alle Threads ausser dem Mainthread zu beenden. Und dann erst System.exit() aufzurufen. Aber auch die Methode ist extrem unsauber. Allein schon, da stop deprecated ist.

Da hat Spike schon recht, am besten auf einen Fix warten, oder nochmal weiter googlen wie andere damit umgehen. So ist die API praktisch ja nicht nutzbar.
 
Was mich blos wundert das selbst System.exit(int) fehlschlägt *ist das überhaupt möglich ?*. Weil System.exit(int) an sich ist ja schon so ein bisschen wie ein gewaltsamer Abbruch der gesamten VM. Sehr merkwürdige API die du da hast.
 
Mit 5 Minuten Google:

http://www.dukascopy.com/wiki/index.php?title=Disconnecting

das solltest du dir mal durchlesen, insbesondere den letzten Satz:
Das habe ich bereits gesehen und verstehe es nicht, was bedeutet die Plattform verwaltet den disconnect selbst? Soll das bedeutet ich kann keine disconnection machen? Weil irgendwo muss das ja möglich sein, sonst bleibt er einfach ewig verbunden bis sich irgendwann die Plattform dazu entscheidet sich zu disconnecten. Das würde bedeuten das der Anwender von der Appliaktion praktisch versklavt wird hihi :D

Also ich glaube das die das extra machen, es gibt dazu bereits zwei Threads (Thread 1 und Thread 2) und das immer unbeantwortet wenn es konkrett um die disconnect Methode geht bzw. das entladen des ClientFactory bzw. IClient Interface. Sie wollen warscheinlich nicht das jemand auch einen vollwertigen Client mit ihrer API baut weil sie selbst bereits einen programmierbaren Client anbieten der übrigens disconnected kann ;). Sonst hätten sie doch längst eine disconnect Methode eingebaut.

Ich versuche gerade dein Vorschlag mit den ThreadGroup, vieleicht klappt das ja irgendwie. Es ist klar nicht die beste Lösung aber was bleibt einem schon übrig, dem Anwender will ich nicht zumuten das er dauernd die App in der Konsole starten muss um von dort aus Ctrl + C zu drücken :rolleyes:

Achja, nachdem die connect Methode aufgerufen wurde, sieht die ThreadGroup so aus:
Code:
sbt.TrapExit$ExitThreadGroup[name=trap.exit,maxpri=10]
    Thread[run-main,5,trap.exit]
    Thread[AWT-XAWT,6,trap.exit]
    Thread[ClientConnector,5,trap.exit]
    Thread[Connection monitor,5,trap.exit]
    Thread[ActivityLogger,5,trap.exit]
    Thread[LocalCacheTimer,5,trap.exit]
    Thread[Flats generator by timeout,5,trap.exit]
    Thread[Curves connection closing timer,5,trap.exit]
    Thread[ClientConnector,5,trap.exit]
    Thread[Connection monitor,5,trap.exit]
    Thread[SocketConnector-0,5,trap.exit]
    Thread[SocketConnectorIoProcessor-0.0,5,trap.exit]
    Thread[DFS_Mina_Thread_1,5,trap.exit]
    Thread[(29113063) Client listeners invocation thread - 1,5,trap.exit]
    Thread[(29113063) Client listeners invocation thread - 2,5,trap.exit]
    Thread[Client listener isolated thread - 1,5,trap.exit]

Und sobald ich die Applikation beende kommen folgende Exceptions:
Code:
27.06.2011 23:44:18,145 ERROR [com.dukascopy.api.impl.connect.a] sleep interrupted
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at com.dukascopy.api.impl.connect.a.run(Unknown Source)
java.lang.InterruptedException
	at java.lang.Object.wait(Native Method)
	at java.lang.Object.wait(Object.java:485)
	at com.dukascopy.transport.client.i.run(Unknown Source)
java.lang.InterruptedException
	at java.lang.Object.wait(Native Method)
	at java.lang.Object.wait(Object.java:485)
	at com.dukascopy.transport.client.i.run(Unknown Source)
java.lang.InterruptedException
	at java.lang.Object.wait(Native Method)
	at java.lang.Object.wait(Object.java:485)
	at com.dukascopy.transport.client.i.run(Unknown Source)
java.lang.InterruptedException
	at java.lang.Object.wait(Native Method)
	at java.lang.Object.wait(Object.java:485)
	at com.dukascopy.transport.client.i.run(Unknown Source)
 
Kann man denn alternativ die Plattform ggf. dazu bringen die Verbindung zu beenden? Ihr also sagen: "Du, ich möchte gerne die Verbindung beenden, mach mal."
 
Soweit mir bekannt ist nein. Also es ist so, die Plattform vom Anbieter ist eine GUI Anwendung in der man Handelssysteme bauen kann (hat einen integrierten Editor), siehe Screenshot im Anhang.

Statt aber in dieser Platform zu coden, kann man mit Eclipse, NetBeans oder einem anderen Editor (ich nutze Emacs) auch extern coden (ohne die Plattform zu starten) wenn man die JForex API bzw. die JAR Datei ins LIB Verzeichnis kopiert, Bsp. für Eclipse würde man so vorgehen: http://www.dukascopy.com/wiki/index.php?title=Use_in_Eclipse

Und von aussen finde ich leider keinen Weg der irgendwie ermöglicht das ganze Konstrukt zu beenden. Ich teste deshalb gerade einige Sachen mit dem ThreadGroup, dabei listete ich mal alle Methoden auf und fand das einige Methoden extra kryptisch unkenntlich gemacht wurden. Warscheinlich ist eines davon die close() Methode um die verbindung zu beenden. Deshalb teste ich gerade mit der invoke() Method der Klasse java.lang.reflect.Method ob durch aufrufen einer dieser Methoden vieleicht zum gewünschten Ergebnis führt :rolleyes:

Das sind zurzeit alle Methoden der jeweiligen Klassen die mittels ThreadGroup gefunden wurden: http://pastebin.com/zpRPZgFZ

Besonders die Klassen "class com.dukascopy.api.impl.connect.a", "class com.dukascopy.transport.client.b" und "class com.dukascopy.transport.client.i" haben kryptische Methoden wie:
stdout hat gesagt.:
+ b( class [Ljava.security.cert.X509Certificate;, class java.lang.String, class java.security.cert.CertificateException )
+ a( class com.dukascopy.transport.client.DisconnectReason )
+ cc( boolean )
+ yJ( )
+ To( )
+ Tm( )
+ Tn( )

Bin mal gespannt ob diese flickerei zum gewünschten Erfolg verhilft :D
 

Anhänge

  • JForex_2.jpg
    JForex_2.jpg
    34,8 KB · Aufrufe: 8
Zuletzt bearbeitet von einem Moderator:
Reflections wäre meine nächste Idee gewesen. Du könntest auch mal gucken ob du an die Quelltexte des Klasse IClient kommst. Darin wird es sehr vermutlich auch einen oder mehrere Sockets geben. Du könntest dir dann über Reflections den Socket holen und manuell schließen. So nimmst du der API die Aufräumarbeit ab die sie ja bei System.exit nicht machen kann.
 
Bitte binde keine Screenshot-Uploads von Fremhostern in deine Posts ein. Dafür gibt es bei Tutorials.de extra die Möglichkeit für Anhänge. Bei Fremhostern gibt es Probleme wie etwa das die Bilder manchmal nicht anklickbar sind um sie in voller Größe betrachen zu können oder sie werden nach einiger Zeit gelöscht. Bitte ändere das um auch späteren Usern eine Möglichkeit auf Erfolg zu gewährleisten.

Was diese "kryptischen" Name angeht : das nennt man "obfuscating" und dient der Blockade von de-Compilern sowie bei teil-offenenm Source unkenntlichmachung der eigentlich Aufgabe. Obfuscating wird meist benutzt wenn nicht gewollt ist das bestimmte Teile des Codes de-compiled oder analysiert werden können. Ich denke das hier das kapital der Entwickler steckt ... sie wollen nur einen Teil der API offen legen ... für den vollen Funktionsumfang wird man aber zur Kasse gebeten ...
 
Zurück