JavaXPCOM JVM Crash evaluating XPath

"mica" <[email protected]>
Newsgroups gmane.comp.mozilla.devel.java
Organization http://groups.google.com
Message-ID <1149587691.918178.26800__2212.80806367776$1149587728$gmane$org@f6g2000cwb.googlegroups.com>
Hello at all,

I'm developer using JavaXPCOM to integrate Firefox in a Java program. I
need evaluate XPath expressions in loaded page. The problem is that JVM
crash while evaluation is made. Some times, the JVM crash quickly and
other times the JVM crash later... but always crash.

I develop a test code. This code load a html page stored in harddisk
and evaluate XPath expression in loaded page. I have test with diferent
html pages, and always JVM crash.

The test code is the follows:

--------------- JAVA CODE BEGINS HERE ---------------

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

import org.eclipse.swt.SWT;
import org.eclipse.swt.browser.MozillaBrowser;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.mozilla.xpcom.Mozilla;
import org.mozilla.xpcom.nsIComponentManager;
import org.mozilla.xpcom.nsIDOMElement;
import org.mozilla.xpcom.nsIDOMHTMLDocument;
import org.mozilla.xpcom.nsIDOMNode;
import org.mozilla.xpcom.nsIDOMXPathEvaluator;
import org.mozilla.xpcom.nsIDOMXPathNSResolver;
import org.mozilla.xpcom.nsIDOMXPathResult;
import org.mozilla.xpcom.nsIRequest;
import org.mozilla.xpcom.nsISupports;
import org.mozilla.xpcom.nsIWebProgress;
import org.mozilla.xpcom.nsIWebProgressListener;

public class XPathJVMCrash {

	protected Display display;

	//MozillaBrowser as found in
	protected MozillaBrowser browser;

	//Field used to count start document events
	private int numStart;

	//Latch used to wait until loading is complete
	private CountDownLatch waitLoadLatch;

	//XPCOM XPath evaluator
	private nsIDOMXPathEvaluator xpathEval;

	public static void main(String[] args) {
		new XPathJVMCrash().test();
	}

	public XPathJVMCrash() {

		initBrowser();

		Mozilla moz = Mozilla.getInstance();
		nsIComponentManager componentManager = moz.getComponentManager();
		String NS_IDOMXPATHEVALUATOR_CONTACTID =
"@mozilla.org/dom/xpath-evaluator;1"; //$NON-NLS-1$
		xpathEval = (nsIDOMXPathEvaluator) componentManager
				.createInstanceByContractID(NS_IDOMXPATHEVALUATOR_CONTACTID,
						null, nsIDOMXPathEvaluator.NS_IDOMXPATHEVALUATOR_IID);

	}

	private void initBrowser() {

		final CountDownLatch initLatch = new CountDownLatch(1);
		new Thread("SWT-Event-Thread") {
			@Override
			public void run() {
				display = new Display();
				final Shell shell = new Shell(display);
				shell.setLayout(new FillLayout());
				browser = new MozillaBrowser(shell,SWT.NONE){
					//Override this method to wait until loading is complete
					@Override
					public void onStateChange(nsIWebProgress aWebProgress, nsIRequest
aRequest, long aStateFlags, long aStatus) {
						super.onStateChange(aWebProgress, aRequest, aStateFlags,
aStatus);
						testOnStateChange(aWebProgress, aRequest, aStateFlags, aStatus);
					}
				};
				initLatch.countDown();
				shell.open();
				while (!shell.isDisposed()) {
					if (!display.readAndDispatch())
						display.sleep();
				}

				display.dispose();
			}
		}.start();
		try {
			initLatch.await();
		} catch (InterruptedException e) {
			throw new Error(e);
		}

	}

	private void testOnStateChange(nsIWebProgress webProgress, nsIRequest
request, long aStateFlags, long status) {
		boolean isDocument = (aStateFlags &
nsIWebProgressListener.STATE_IS_DOCUMENT) != 0;
		boolean start = (aStateFlags & nsIWebProgressListener.STATE_START) !=
0;
		boolean stop = (aStateFlags & nsIWebProgressListener.STATE_STOP) !=
0;

		if (isDocument) {
			if (start) {
				numStart++;
			} else if (stop) {
				numStart--;
				if (numStart == 0) {
					waitLoadLatch.countDown();
				}
			}
		}
	}

	private void test() {

		for(int i=0; i<100; i++){

			System.out.println("Load "+i);

			waitLoadLatch = new CountDownLatch(1);
			display.syncExec(new Runnable(){
				public void run() {
					browser.setUrl("file://O:/wpLokku/JXPCOMBrowserTest/search.htm");
				}
			});
			try {
				waitLoadLatch.await();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}

			for(int j=0; j<100; j++){
				System.out.print(".");
				for(nsIDOMNode node: xpathNodes("//*[@class='l']",
browser.getDocument())){
					nsIDOMElement element = (nsIDOMElement)
node.queryInterface(nsIDOMElement.NS_IDOMELEMENT_IID);
					String text = element.getFirstChild().getNodeValue();
				}
			}
			System.out.println();
		}

	}

	public List<nsIDOMNode> xpathNodes(String xpath, nsIDOMNode context) {

		nsIDOMHTMLDocument document = browser.getDocument();

		nsIDOMXPathNSResolver res = xpathEval.createNSResolver(document);
		nsISupports obj = xpathEval.evaluate(xpath, context, res,
				nsIDOMXPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

		nsIDOMXPathResult result = (nsIDOMXPathResult) obj
				.queryInterface(nsIDOMXPathResult.NS_IDOMXPATHRESULT_IID);

		List<nsIDOMNode> rNodes = new ArrayList<nsIDOMNode>();

		for(int i=0; i<result.getSnapshotLength(); i++){
			rNodes.add(result.snapshotItem(i));
		}

		return rNodes;
	}
	
}

--------------- JAVA CODE ENDS HERE ---------------
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.