SWT mit OLE-Objekt und aktualisierung per RMI

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

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();
		}
	}
	
}
 
Zurück