AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Delphi mit Java komunizieren

Offene Frage von "bucchi"
Ein Thema von Simon1988 · begonnen am 12. Jul 2006 · letzter Beitrag vom 27. Okt 2006
Antwort Antwort
Seite 2 von 8     12 34     Letzte »    
Robert Marquardt
(Gast)

n/a Beiträge
 
#11

Re: Delphi mit Java komunizieren

  Alt 25. Jul 2006, 17:24
Der Anlaufpunkt fuer das JNI mit Delphi ist http://www.pacifier.com/~mmead/jni/delphi/ aber ich glaube dieser Link ist schon bekannt.
Es empfiehlt sich Eclipse zu installieren fuer die Java-Entwicklung.
Das JNI zeigt auch wie man eine Java-Klasse in einer DLL implementiert. Die Implementierung kann dann in jeder beliebigen Sprache einschliesslich Delphi erfolgen.
Bei Code Mercenaries machen wird das mit unserem DLL API. Die normalen Funktionen werden auch als Methoden einer Java-Klasse exportiert und damit kann Java die DLL direkt benutzen.
Ein bischen Glue-Code in der Implementierung der Methode, der die Anpassung der Parameter handhabt und die Originalfunktion aufruft, genugt.
Macht man die DLL in C, dann ist dieser Glue-Code auch noch portabel und funktioniert auch unter Linux.
  Mit Zitat antworten Zitat
Simon1988

Registriert seit: 12. Jul 2006
39 Beiträge
 
#12

Re: Delphi mit Java komunizieren

  Alt 27. Jul 2006, 00:24
hey,
ok .. soweit so gut. Jetzt hab ich noch eine frage zum nächsten Schritt. Ich kenne mich mit Java nicht sonderlich gut aus. Weiß also nicht welche Dateien man mit java erstellen kann (ob *.exe oder *.jar oder was auch immer ^^) Welches Dateiformat brauche ich denn jetzt um es in Delphi einbinden zu können ?
und wo steht dann im Delphiquelltext der Pfad dieser Datei. Also das sollte ja in dem Link beschrieben sein. Aber ich finde den Pfad halt nicht
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#13

Re: Delphi mit Java komunizieren

  Alt 27. Jul 2006, 10:42
In Java gibt es eigentlich nur 3 wirklich wichtige Dateitypen.
Der Quellcode wird in .java Dateien abgelegt. Mittels javac können diese dann in .class Dateien Übersetzt werden.
Eine .class Datei besteht aus einem Objektcode. Dieser ist auf einer Virtuellen Maschine (JVM) Lauffähig. Die .class Dateien enthalten nur den übersetzten Code und lassen damit keinen Rückschluß auf die eigentlichen Sourcen zu. Wichtig ist hier die Technik der JVM. Code wird immer so gelinkt, dass er von einer bestimmten Plattform ausgeführt werden kann. In diesem Fall gibt es halt eine virtuelle Plattform. .exe Dateien laufen halt unter einem bestimmten Windows. Bei 32-bit exen auf einem Win 3.0 dürftest du aber schon Probleme haben. Linux, Solaris, AIX, ... wüßten aber gar nichts mit einer solchen Datei anzufangen.
Bei Java ist die Plattform genauso festgelegt, aber virtuell. Hast du eine JVM für deine eigentliche Zielplattform (z.B. Windows X, MacOS Y, ...) dann kannst du auf dieser den Objektcode ausführen.
Die letzte wichtige Datei ist dann noch die .jar. Hierbei handelt es sich eigentlich nur um ein Archiv. Ein Projekt wird schnell größer als ein zwei Dateien. Zudem verwendest du sicherlich früher oder später Klassen, die du für ein anderes Projekt geschrieben hast. Um hier eine einzelne Datei weiterreichen zu können, hat man sich (sinnvoller Weise) für eine Archiv entschieden. Dieses kann in Java transparent eingebunden werden (die Struktur der .jar wird dann nicht von der entpackten auf deiner Platte unterschieden). Ein jar ist glaube ich in erster Linie wirklich an ein .tar angelehnt, es nimmt erstmal nur Dateien auf. Es gibt jedoch noch weitere Optionen. Die eine wichtige ist, dass du die Dateien mit einem zip Algorithmus packen lassen kannst (unterstütz jar aus deinem JDK). Die andere wichtige Option ist, dass du ein Manifest angeben kannst. Unteranderem kann in dieser Datei der Classpath gesetzt werden und wichtiger, du kannst eine zu startende Datei angeben. Startest du dann dein Programm mittels javaw -jar DeinJar.jar oder java -jar DeinJar.jar, so wird automatisch diese .class Datei ausgeführt.
Um deine Frage zu beantworten, in Java werden ausführbar eigentlich nur .class Dateien erzeugt. Da eine .jar einfach transparent eingebunden werden kann, gibt es zwar startbare Archive, aber für die JVM ist es auch nur das starten einer .class in einem bestimmten Pfad.

Zu der anderen Frage komme ich gleich (muss mir mal das Beispiel anschauen)
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#14

Re: Delphi mit Java komunizieren

  Alt 27. Jul 2006, 10:48
So, zu deiner Frage wo genau die Dateien liegen müssen:
Wie gesagt, es sind die .class Dateien, die Java sucht. Was hier das Schlüsselwort ist (und mit dem Wissen dass es .class Dateien sind ist es auch sofort klar) "ClassPath". Dies ist so zu sagen der Suchpfad von Java. Hier kannst du entweder den direkten Pfad zu den einzelnen Klassen oder halt zu einem .jar angeben. In diesen würde dann nach der jeweilige Klasse gesucht werden (also ein wenig wie PATH unter Windows).
  Mit Zitat antworten Zitat
Simon1988

Registriert seit: 12. Jul 2006
39 Beiträge
 
#15

Re: Delphi mit Java komunizieren

  Alt 27. Jul 2006, 11:05
gut. das heißt also ich brauch zu jeder klasse eine .class datei.
und geladen wird sie indem die Optionen für die JVM setzt

Meine Datei heißt HelloWorld.class und liegt im gleichen Ordner.

Delphi-Quellcode:
  // Set the options for the VM
    Options[0].optionString := './HelloWorld.class';
{den Pfad hab ich auch mal ohne Punkt ausprobiert}
    VM_args.version := JNI_VERSION_1_2;
    VM_args.options := @Options;
    VM_args.nOptions := 1;
jetzt kommt aber im direkten weiteren Verlauf des Quelltextes ein Fehler, was mich darauf schließen lässt, dass er die Datei "HelloWorld.class" nicht gefunden hat.
Delphi-Quellcode:
      // Load the VM
    Errcode := JavaVM.LoadVM(VM_args);
    if Errcode < 0 then
    begin
      ShowMessage(Format('Error loading JavaVM, error code = %d', [Errcode]));
      Exit;
    end;
Da wird eben die ShowMessage mit dem ErrorCode -1 ausgegeben
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#16

Re: Delphi mit Java komunizieren

  Alt 27. Jul 2006, 14:02
Jede Klasse wird automatische in eine .class gepackt. Du solltest (einfach weil es sauber ist) für jede öffentliche Klasse auch immer eine eigene Datei verwenden (was anderes erlaubt Java auch gar nicht!). Mehrere Klassen in einer Datei macht keine Sinn. Zusammengehörigkeit sollte man ja durch das package erzeugen.
Was dein Problem angeht, so weiß ich nicht genau was du mit
Options[0] := './HelloWorld.class'; genau erreichen willst.
Ich glaube da kommen wir nicht um ein wenig mehr Theorie zur Vorgehensweise rum. Ich hoffe ich kann es halbwegs verständlich (und korrekt) erklären. Java läuft wie gesagt immer plattform-unabhängig in der virtuellen Maschine. Diese Virtuelle Maschine muss einmal für jede Plattform entwickelt werden, die Java unterstützen soll. Der Vorteil ist halt, dass du nur ein Programm (die virtuelle Maschine) für die Plattform schreiben musst. Genau genommen musst nicht mal du das tun, für die großen Plattformen macht das SUN.
Du schreibst deine Programme nur einmal und sie laufen überall.
Sprachen wie Delphi, C und C++ sind hingegen Plattformspezifisch. Das stimmt so auch nicht 100%ig. Eine C Datei kann so geschrieben werden, dass man Code für verschiedene Plattformen aus ihr ohne Änderung erzeugen kann, aber wenn sie werden halt für eine Plattform (gegen entsprechende Bibliotheken) gelinkt. Du bekommst halt unter Windows eine .exe. Bei den Unix Derivaten gibt es dann ausführbare Dateien (die Erweiterung ist egal). Bibliotheken unter Windows werden dann in .dlls gelinkt, unter Linux in .so usw. Code der so gelinkt wurde, kann nativ von der entsprechenden Plattform ausgeführt werden.
Die JVM muss wie gesagt mind. einmal für jede Plattform geschrieben werden, die Java unterstützt. Die JVM besteht somit aus nativem Code. JNI ist jetzt eine Java Schnittstelle zur nativen Welt (also der Plattform auf dem die JVM läuft). Code der nativ aufgerufen wird, ist dann auch wirklich an die jeweilige Plattform gebunden!
Die JVM ist jetzt sozusagen ein Vermittler. Java Code für die Virtuelle Maschine wird hier in native Befehle umgesetzt. In welche hängt von der Plattform ab, aber du musst dich eben nicht drum kümmern. Das Java Native Interface funktioniert jetzt aber in Beide Richtungen. Das heißt wenn du nativen Code in Java verwenden möchtest, wird der halt in der anderen Richtung umgewandelt.
Du hast also etwas wie NATIV <--> JVM <--> Java Code
Alles was gemacht wird, läuft also immer über die JVM.

In deinem Fall ist die Native Aussenwelt dein Delphi. Delphi kann nichts mit Java Klassen anfangen und diese nichts mit Delphi. Bei der JVM sieht dass anders aus. Delphi kann hier auf native Schnittstellen zur JVM zugreifen und umgekehrt. Anders gesagt, Delphi kommuniziert jetzt mit der JVM, die arbeitet den Java Code ab und gibt das Ergebnis an Delphi weiter.
Das sind nur grob die Grundlagen, warum du dir eine Instanz der JVM in Delphi holst.

Unter Windows kennst du sicherlich Pfade. Der Suchpfad PATH z.B. enthält alle Ordner, die nach Anwendungen durchsucht werden. Tippst du einen Befehl auf der Konsole ein, so gibt es drei Möglichkeiten:
1) Er liegt im aktuellen Verzeichnis und wird ausgeführt
2) Windows findet ihn im Suchpfad und er wird ausgefürht
3) er wird nicht gefunden

Das Windows einen solchen Suchpfad kennt ist zwar schön, hat aber wenig zu bedeuten. Einerseits soll ja Java auf allen Plattformen lauffähig sein (nicht jede muss einen Suchpfad haben) und ausserdem muss Java nur die Lage von .class und .jar Dateien kennen. Die kann Windows (oder eine andere Plattform) aber nicht ausführen. Also würde ein Suchpfad unnötig groß werden. Die Lösung ist einfach, die JVM schafft sich ihren eigenen Suchpfad. Dieser wird halt treffender Weise mit ClassPath bezeichnet. Du kannst den entweder global für deine jeweilige Plattform setzen oder als Argument beim Start mitgeben. Alle Klassen auf die Java zugreifen können soll, müssen im Classpath bekannt gemacht werden. Du kannst entweder alle Klassen einzeln angeben oder sie in ein .jar packen und dieses in den ClassPath einfügen.
Steht eine Klasse nicht im Pfad, kann sie nicht gefunden werden. Ohne Angabe eines ClassPath wird (denke ich) die JVM nur im aktuellen Ordner (in ihrem Fall das bin Verzeichnis des JRE) nachschauen. Liegt hier keine .class, pech.

So, damit wären wir auch schon bei deinem Aufruf. Hoffe hab dich nicht schon jetzt gelangweilt, ein klein wenig kommt noch. Dein Delphi Programm möchte auf Java-Code zugreifen, muss also den Weg über die Schnittstelle JNI gehen. Dies tust du, indem du dir eine Instanz der JVM holst. Wo diese Instanz genau herkommt weißt du eigentlich nicht so recht (rein aus Delphi Sicht). Die Frage ist, ob du es wissen musst. Eigentlich nein!
Hast du die Java-Datei, die du ausführen möchtest, so kennst du auch ihren Pfad. Damit kannst du den einfach bekannt machen. Den Klassenpfad machst du der JVM bei ihrem Start bekannt. Hierzu musst einfach -Djava.class.path=<ClassPathEintrag> als Option mit an die JVM geben. Du solltest dich da echt an das Bsp. von der Seite 2 halten! Gibst du nur einen Klassennamen an, weiß die JVM nichts damit anzufangen.
Klar, sie könnte die Klasse einfach einmal ausführen und fertig. Aber das möchtest du ja nicht, du möchtest ja, dass Delphi mit dieser Klasse kommunizieren kann.
Diese Option solltest du also übergeben. Dann weiß die JVM, dass es eine solche Klasse im Suchpfad gibt.

Hast du die JVM in Delphi gestartet, holst du dir von der jetzt einen Zugriff auf das JNI. Dies ist die Brücke über die nativ (Delphi) mit Java kommuniziert. Du holst dir eine Instanz von TJNIEnv. Über diese Instanz finden dann die Aufrufe statt (und werden entsprechend übersetzt).
Alles was du nun machst entspricht so ziemlich dem, was du in den JNI Texten von Sun findest. Du hast natürlich statt C eine Delphi Kapselung, aber im Prinzip tust du das gleiche.
Mittels FindClass kannst du dir die Klasse die du aufrufen möchtest zurückgeben lassen. Hierbei sucht das JNIEnv einfach im Classpath der JVM nach der entsprechenden Klasse und liefert dir eine Adresse über die du sie erreichst. Hast du eine Klasse, kannst du in dieser wiederum nach Methoden und Variablen suchen. Du bekommst (unter C zumindest) immer eine ID, die du für den entsprechenden Aufruf mit angeben musst. Wichtig ist hier immer zu schauen, dass du eine gültige Adresse bekommst.
Wie das konkret für Delphi aussieht müsste auch ich erst nachlesen, denke aber das findest du schon!
Grob gibt es halt die JNI Seiten von Sun an denen du dich orientieren kannst. Da werden Beispiele zwar in C (ausser man hat es geändert) angegeben, was die Syntax nicht sehr Delphi ähnlich macht, aber verstehen wirst du die schon!
env* entspricht dann halt deiner Klasse TJNIEnv, ähnlich leicht sind andere Entsprechungen zu erkennen. Die Signatur der Methoden kann natürlich in der Delphi Kapselung exakt der von JNI entsprechen oder (da es eine Kapselung ist) auch abweichen. Deswegen möchte ich hier erstmal nichts falsches sagen.

Hoffe du hast grob verstanden warum du wirklich den Klassenpfad setzten musst und nicht den Namen einer Datei angeben reicht.
  Mit Zitat antworten Zitat
Simon1988

Registriert seit: 12. Jul 2006
39 Beiträge
 
#17

Re: Delphi mit Java komunizieren

  Alt 28. Jul 2006, 13:32
hey. danke .. das war echt ne super erklärung . Jetzt hab ich das verstanden denk ich .. zumindest in der Theorie. in der Praxis sieht es ganz anders aus. Hier meine procedure, die ich geschrieben hab.
Eigentlich ist es ja zum größten Teil erstmal nur abgeschrieben aber egal ..

Also ich habe in dem Order C:\Projekt Java\Delphi Code\
2 Klassen. Einmal Main.class und einmal HelloWorld.class. in die InputBox habe ich nun diesen Pfad C:\Projekt Java\Delphi Code\ angegeben

Aber bei dem Punkt //Load the VM bricht er ab. mit demm error -1

Delphi-Quellcode:
procedure TForm1.FormCreate(Sender: TObject);
Var ClassPath : string;
begin
try
 JavaVM := TJavaVM.Create;
  // Set the options for the VM
    ClassPath := InputBox('JavaD','Enter the Java classpath',
    'C:\Projects\DJNI\classes');

    FillChar(Options, SizeOf(Options), #0);
    Options[0].optionString :=
    PChar('-Djava.class.path=' + ClassPath);

    VM_args.version := JNI_VERSION_1_2;
    VM_args.options := @Options;
    VM_args.nOptions := 1;
{hier bricht er ab}
      // Load the VM
    Errcode := JavaVM.LoadVM(VM_args);
    if Errcode < 0 then
    begin
      ShowMessage(Format('Error loading JavaVM, error code = %d', [Errcode]));
      Exit;
    end;

      // Create a Java environment from the JVM's Env (another wrapper class)
    JNIEnv := TJNIEnv.Create(JavaVM.Env);

      // Find the class in the file system. This is why we added
      // the current directory to the Java classpath above.
    Cls := JNIEnv.FindClass('HWJava');
    if Cls = nil then
    begin
      ShowMessage('Can''t find class: HWJava');
      Exit;
    end;

      // Find the static method 'printHello' within the HWJava class
    Mid := JNIEnv.GetStaticMethodID(Cls, 'printHello', '()V');
    if Mid = nil then
    begin
      ShowMessage('Can''t find method: printHello');
      Exit;
    end;

      // Call the static method
    JNIEnv.CallStaticVoidMethod(Cls, Mid, []);

  except
    on E : Exception do
      ShowMessage('Error: ' + E.Message);
  end;

end;
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#18

Re: Delphi mit Java komunizieren

  Alt 28. Jul 2006, 13:44
Hm, entschuldigst du dich gerade dafür, dass du einen (so unscheinbaren) Beitrag übersehen hast?

Wenn das mal nicht mir rausschmiss aus der DP geandet wird...
  Mit Zitat antworten Zitat
Simon1988

Registriert seit: 12. Jul 2006
39 Beiträge
 
#19

Re: Delphi mit Java komunizieren

  Alt 28. Jul 2006, 14:36
sorry ,dass ichs erst übersehen habe .. tut mir leid. IHR DÜRFT MICH JETZT RAUSSCHMEIßEN (nein scherz .. tut das bitte nicht) ..aber die Erklärung vorhin zur JVM von dir war echt sehr gut..^^


aber das nächste prob hab ich schon gepostet .. da kommt immer noch der Errorcode -1 ^^
  Mit Zitat antworten Zitat
Der_Unwissende

Registriert seit: 13. Dez 2003
Ort: Berlin
1.756 Beiträge
 
#20

Re: Delphi mit Java komunizieren

  Alt 28. Jul 2006, 14:48
Danke erstmal für die Blumen.
Ja, werd mal Daniel oder so bescheid sagen, denke da versteht der dann auch keinen Spaß!

Was dein Problem angeht, so hab ich eine Vermutung woran das liegen könnte. Also für deine Testzwecke kannst du natürlich die Eingabebox weglassen. Du kannst erstmal einen Pfad statisch im Source setzen (oder halt die Eingabe nehmen, was für dich praktischer ist). Jedenfalls gibt es hier mehrere Fallen, in die du tappen kannst. Die eine (ich denke die ist hier das Problem) liegt darin, dass Leerzeichen im Pfad sich immer schlecht machen. Versuch es einfach mal mit den üblichen Verdächtigen, in dem Fall also "dein Pfad mit Leerzeichen" und / oder damit, dass du einfach einen Pfad ohne Leerzeichen nimmst (e.g. C:\Test). Die andere Sache (die hier aber nicht zu treffen dürfte) ist, dass Java das \ als Escape zeichen ansieht, da du hier aber nichts direkt an ein Programm übergibst, solltest das noch kein Problem sein. Liegt es nicht am Leerzeichen kannst du noch zusätzlich das Escapen von \ in \\ versuchen (also C:\\...)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 8     12 34     Letzte »    


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:48 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz