mcdroemmel
Mitglied
Hallo zusammen,
habe da wohl ein verzwicktes Problem wo ich echt Hilfe benötige.
Zweck:
Ich habe eine Java Anwendung, die SWT zur Visualisierung nutzt.
Und zwar will ich von meinem Java-App-Server per RMI eine entfernte Anwendung rufen, die dann mit Hilfe von SWT und dem dort per OLE integrierten Internet-Explorer die Daten visualisiert. Die gefeuerte RMI Methode soll also quasi eine Aktivität in dem OLE-Objekt (Internet-Explorer) auslösen.
Bisher ist das wie folgt realisiert:
Mit SWT definiere ich einen OLE-Frame und steuere den Internet-Explorer als OLE-Objekt. Der IE startet einmalig eine URL. In dieser URL ist wiederum ein Active-X-Control eingebettet. Dieses Active-X-Control wird dann von meiner Java-Anwendung indirekt über Javascript der aufgerufenen HTML-Seite angesteuert.
Dieses Active-X startet ein grafisches Tool im Explorer. Das Control ist leider nicht direkt per OLE ansteuerbar. Meine Java-Anwendung startet dann im IE wie gesagt eine Java-Script-Funktion die dann das Active-X veranlasst jeweils eine neue Grafik zu verarbeiten.
Soweit so gut. Das ganze funktioniert mit unterschiedlichen Aufrufen der JS-Funktion wenn ich das z.B. von unterschiedlichen Buttons in SWT ansteuere.
Jetzt kommt RMI ins Spiel.
Nämlich die ganze Anwendung soll nämlich nicht interaktiv über Buttons, sondern von einem Java-App-Server aus getriggert werden (einer Bean um genau zu sein), der die zu visualisierenden Daten hält.
Also Server ruft per RMI meine Java-Client-Anwendung (nur JRE). Eine Methode meines RMI-Objektes soll dann die Java-Methode meiner Visualisierung aufrufen, die ihrerseits dann im IE per OLE die Javascript-Funktion startet.
RMI an sich funktioniert. Visualisierung in SWT mit OLE im IE auch.
Aber wenn meine RMI-Methode (die als Parameter das Objekt erhält welches die UI steuert) dann die SWT-Visualisierungsmethode aufruft fliegt mir die JVM um die Ohren mit EXCEPTION_ACCESS_VIOLATION (0xc0000005)
Jetzt hab ich schon gelesen das das wohl was mit Threads zu tun haben wird. Die Methode des RMI-Objekts läuft ja wohl in einem anderen Thread als dem, der das SWT-UI erzeugt hat.
Wie kann ich das Problem lösen? Mit eigener Thread-Steuerung hab ich nicht so wahnsinnig viel Erfahrung bisher.
So sieht der Quellcode (gekürzt) im wesentlichen aus (bitte keine Syntax-Fehler melden..können durch die Kürzung reingekommen sein):
Vielen lieben Dank im Vorraus für Eure Unterstützung:
McD
Das Objekt mit meiner Main-Methode. Sie erzeugt das Objekt mit dem UI und erzeugt Registry und das Binding für das RMI-Objekt
meine RMI-Klasse Kall2FpViewer hier. Die Methode createJPG ist die Methode die vom App-Server aufgerufen wird:
meine Visualisierungs-Klasse (gekürzt, könnte sein das deshalb vielleicht mal ne Klammer oder so fehlt, aber vom Prinzip ****t es ja wenn das Teil per Buttons, die hier jetzt weggelassen wurden, getriggert wird)
habe da wohl ein verzwicktes Problem wo ich echt Hilfe benötige.
Zweck:
Ich habe eine Java Anwendung, die SWT zur Visualisierung nutzt.
Und zwar will ich von meinem Java-App-Server per RMI eine entfernte Anwendung rufen, die dann mit Hilfe von SWT und dem dort per OLE integrierten Internet-Explorer die Daten visualisiert. Die gefeuerte RMI Methode soll also quasi eine Aktivität in dem OLE-Objekt (Internet-Explorer) auslösen.
Bisher ist das wie folgt realisiert:
Mit SWT definiere ich einen OLE-Frame und steuere den Internet-Explorer als OLE-Objekt. Der IE startet einmalig eine URL. In dieser URL ist wiederum ein Active-X-Control eingebettet. Dieses Active-X-Control wird dann von meiner Java-Anwendung indirekt über Javascript der aufgerufenen HTML-Seite angesteuert.
Dieses Active-X startet ein grafisches Tool im Explorer. Das Control ist leider nicht direkt per OLE ansteuerbar. Meine Java-Anwendung startet dann im IE wie gesagt eine Java-Script-Funktion die dann das Active-X veranlasst jeweils eine neue Grafik zu verarbeiten.
Soweit so gut. Das ganze funktioniert mit unterschiedlichen Aufrufen der JS-Funktion wenn ich das z.B. von unterschiedlichen Buttons in SWT ansteuere.
Jetzt kommt RMI ins Spiel.
Nämlich die ganze Anwendung soll nämlich nicht interaktiv über Buttons, sondern von einem Java-App-Server aus getriggert werden (einer Bean um genau zu sein), der die zu visualisierenden Daten hält.
Also Server ruft per RMI meine Java-Client-Anwendung (nur JRE). Eine Methode meines RMI-Objektes soll dann die Java-Methode meiner Visualisierung aufrufen, die ihrerseits dann im IE per OLE die Javascript-Funktion startet.
RMI an sich funktioniert. Visualisierung in SWT mit OLE im IE auch.
Aber wenn meine RMI-Methode (die als Parameter das Objekt erhält welches die UI steuert) dann die SWT-Visualisierungsmethode aufruft fliegt mir die JVM um die Ohren mit EXCEPTION_ACCESS_VIOLATION (0xc0000005)
Jetzt hab ich schon gelesen das das wohl was mit Threads zu tun haben wird. Die Methode des RMI-Objekts läuft ja wohl in einem anderen Thread als dem, der das SWT-UI erzeugt hat.
Wie kann ich das Problem lösen? Mit eigener Thread-Steuerung hab ich nicht so wahnsinnig viel Erfahrung bisher.
So sieht der Quellcode (gekürzt) im wesentlichen aus (bitte keine Syntax-Fehler melden..können durch die Kürzung reingekommen sein):
Vielen lieben Dank im Vorraus für Eure Unterstützung:
McD
Das Objekt mit meiner Main-Methode. Sie erzeugt das Objekt mit dem UI und erzeugt Registry und das Binding für das RMI-Objekt
Code:
private static final Logger log = Logger.getLogger( FpViewer.class.getName() );
public static void main(String[] args) {
Registry r;
try
{
// UI aufbauen
Display display = Display.getDefault();
Shell shell = new Shell(display);
FpViewerUI ui = new FpViewerUI(shell, SWT.NULL, log);
Point size = ui.getSize();
shell.setLayout(new FillLayout());
shell.layout();
if(size.x == 0 && size.y == 0) {
ui.pack();
shell.pack();
} else {
Rectangle shellBounds = shell.computeTrim(0, 0, size.x, size.y);
shell.setSize(shellBounds.width, shellBounds.height);
}
RMISocketFactory.setSocketFactory(new FixedPortRMISocketFactory());
r = LocateRegistry.createRegistry(28000);
// RemoteServer.setLog( System.out );
System.out.println("Binde Klasse Kall2FpDevRMI an Server...");
log.log(Level.INFO,"Binde Klasse Kall2FpDevRMI an Server...");
r.bind("IKall2FpViewer", new Kall2FpViewer(log,ui));
System.out.println("Starte UI-Loop");
shell.open();
// UI-Loop
while (!shell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
meine RMI-Klasse Kall2FpViewer hier. Die Methode createJPG ist die Methode die vom App-Server aufgerufen wird:
Code:
public class Kall2FpViewer extends UnicastRemoteObject implements IKall2FpViewer {
public static final long serialVersionUID = 4711;
private Logger log;
private FpViewerUI ui;
public Kall2FpViewer (Logger logger, FpViewerUI fpViewerUI) throws RemoteException
{
super ();
// Daten im Objekt sichern
log = logger;
ui = fpViewerUI;
}
public boolean createJPG(String fileName, String guid) {
ui.startJPGRendering(fileName, guid);
return false;
}
}
meine Visualisierungs-Klasse (gekürzt, könnte sein das deshalb vielleicht mal ne Klammer oder so fehlt, aber vom Prinzip ****t es ja wenn das Teil per Buttons, die hier jetzt weggelassen wurden, getriggert wird)
Code:
public class FpViewerUI extends org.eclipse.swt.widgets.Composite {
public FpViewerUI(Composite parent, int style, Logger) {
super(parent, style);
browserAvailable = false;
initGUI();
log = logger;
}
public boolean startJPGRendering (String fileName, String guid)
{
System.out.println("In startJPGRendering");
boolean result = false;
if (this.browserAvailable)
{
int[] htmlDocumentID = browser.getIDsOfNames(new String[] { "Document" });
System.out.println("htmlDocumentID="+htmlDocumentID);
if (htmlDocumentID == null)
return result;
Variant pVarResult = browser.getProperty(htmlDocumentID[0]);
System.out.println("pVarResult="+pVarResult);
if (pVarResult == null || pVarResult.getType() == 0)
return result;
// IHTMLDocument2
OleAutomation htmlDocument = null;
try {
htmlDocument = pVarResult.getAutomation();
pVarResult.dispose();
int[] scriptID = htmlDocument.getIDsOfNames(new String[] { "Script" });
System.out.println("scriptID="+scriptID);
if (scriptID == null)
return result;
pVarResult = htmlDocument.getProperty(scriptID[0]);
System.out.println("pVarResult2="+pVarResult);
if (pVarResult == null || pVarResult.getType() == 0)
return result;
OleAutomation htmlWindow = null;
try {
// IHTMLWindow2
htmlWindow = pVarResult.getAutomation();
pVarResult.dispose();
int[] evaluateID = htmlWindow.getIDsOfNames(new String[] { "testGenerate" });
System.out.println("testGenerateId="+evaluateID);
if (evaluateID == null)
return result;
String expression = fileName;
Variant[] rgvarg = new Variant[] { new Variant(
fileName), new Variant(guid) };
pVarResult = htmlWindow.invoke(evaluateID[0], rgvarg,
null);
if (pVarResult == null || pVarResult.getType() == 0)
return result;
System.out.println(expression + " ="
+ pVarResult.getString());
result = true;
} finally {
htmlWindow.dispose();
}
} finally {
htmlDocument.dispose();
}
}
System.out.println("Raus startJPGRendering");
return result;
}
/**
* Initializes the GUI.
*/
private void initGUI() {
try {
FormData composite1LData = new FormData();
composite1LData.width = 700;
composite1LData.height = 500;
composite1 = new Composite(this, SWT.NONE);
GridLayout composite1Layout = new GridLayout();
composite1Layout.makeColumnsEqualWidth = true;
composite1.setLayout(composite1Layout);
composite1.setLayoutData(composite1LData);
{
OleFrame frame = new OleFrame(composite1, SWT.NONE);
site = new OleControlSite(frame, SWT.NONE, "Shell.Explorer");
site.doVerb(OLE.OLEIVERB_INPLACEACTIVATE);
site.setBounds(5, 0, 700, 500);
browser = new OleAutomation(site);
// When the document is loaded, access the document object for the new
// page
// and evalute expression using Script.
int DownloadComplete = 104;
site.addEventListener(DownloadComplete, new OleListener() {
public void handleEvent(OleEvent event) {
browserAvailable = true;
System.out.println("browserAvailable set");
int[] htmlDocumentID = browser.getIDsOfNames(new String[] { "Document" });
System.out.println("htmlDocumentID="+htmlDocumentID);
if (htmlDocumentID == null)
return;
Variant pVarResult = browser.getProperty(htmlDocumentID[0]);
System.out.println("pVarResult="+pVarResult);
if (pVarResult == null || pVarResult.getType() == 0)
return ;
// IHTMLDocument2
OleAutomation htmlDocument = null;
try {
htmlDocument = pVarResult.getAutomation();
pVarResult.dispose();
} finally {
htmlDocument.dispose();
}
}
});
int[] ids = browser.getIDsOfNames(new String[] { "Navigate", "URL" });
Variant[] rgvarg = new Variant[] { new Variant("file://myhtml.html") };
int[] rgdispidNamedArgs = new int[] { ids[1] };
browser.invoke(ids[0], rgvarg, rgdispidNamedArgs);
System.out.println("Nach brower.invoke");
}
this.layout();
} }
catch (Exception e) {
e.printStackTrace();
}
}
}