Re: XPCOM Component Written in Java
Derrick Rice <[email protected]> Mon, 26 Jan 2009 08:11:14 -0800 (PST)
| Newsgroups | gmane.comp.mozilla.devel.java |
|---|---|
| Organization | http://groups.google.com |
| Message-ID | <[email protected]> |
On Jan 26, 9:41 am, Alberto <[email protected]> wrote: > On Jan 23, 11:16 pm, Derrick Rice <[email protected]> wrote: > > > > > I've also posted this to the mozswing mailing list, since that's what > > I'm using. But this seems to be a core XPCOM problem I'm having. > > > Let me just say that this I am not looking to start a VM from > > mozilla... my entire application is java, with mozilla used via JNI > > (mozswing/JavaXPCOM). What I want to know is why my components cannot > > be directly access by the javascript, yet they seem to interact in > > other ways. > > > ------------------------------------------ > > > What is so confusing is that I see the javascript > > successfully interacting with the java, but as soon as I attempt to > > explicitly call a function, it falls. > > > Goal: Create a new XPCOM component which will be written in Java and > > installed in my mozswing application. Use it from javascript. > > > Steps and results: > > > 1. Create a new interface idl and compile it into an *.xpt and java > > interface. [OK] > > 2. On mozswing initialization, install a factory for this interface > > that will generate java objects. This is no different than how I've > > installed java factories for other already existing interfaces.[OK] > > 3. After installing the factory, add the component to the "JavaScript > > global property" category, so that it is accessible to website > > javascript. [OK] > > 4. Since the interface extends nsIClassInfo and my component (which I > > generate in the factory) can also queryInterface to > > nsISecurityCheckedComponent, I can allow it to be used from the web > > page. > > > *** At this point I can successfully create and invoke my component > > through XPCOM with JAVA: > > XPCOMUtils.create("<contract id>", myInterface.class).callFunction() > > > 5. Generate a test HTML page with javascript that accesses the item > > [This is where things go bad] > > > var instance = window.myComponent.QueryInterface > > (Components.interface.nsIMyNewInterface); > > alert(instance); // yields [xpconnect wrapped > > nsIMyNewInterface] > > alert(instance.member); // yields the value of the member > > alert(instance.callFunction); // yields function > > callFunction() { [native code] } > > instance.callFunction(); // generates an error, see below > > > [Exception... "Component returned failure code: 0x80004001 > > (NS_ERROR_NOT_IMPLEMENTED) [nsIMyNewInterface.callFunction]" > > nsresult: "0x80004001 (NS_ERROR_NOT_IMPLEMENTED)" location: "JS frame > > :: webpage.html :: run :: line 15" data: no] > > > If I throw print statements into my java component, I see it being > > access (QueryInterface is called and so are the > > nsISecurityCheckedComponent functions). This indicates to me that > > it's clearly possible for the javascript to communicate with the java. > > It's already taking place when I call QueryInterface. But if I try > > to call something else, it fails. > > > Am I running into a natural limitation of JavaXPCOM? How can I > > communicate back to my existing java application from javascript > > XPCOM? > > > Problems solved: > > * accessing XPCOM from javascript > > * installing XPCOM factories from java > > * making components visible and accessible to webpages > > > Problems existing: > > * using my components from javascript > > > I saw someone else had this problem but saw no solution:http://osdir.com/ml/mozilla.devel.java/2006-01/msg00007.html > > > Again, any help here would be seriously appreciated. Even if it's > > just a little insight. > > Even if i'm some step behind you i guess I could probably help you. > I succeded (from java,not javascript yet) to register the XPcom object > created implementing the interface and to access its method. > What I'm still not able to do is register the XPcom object > independently from running the java code,either in a dynamic way or in > a static one. > Since I guess you succeeded in doing that can you help me out? > Thanks in advance I don't know if I 100% understand your question, but I'll give 2 answers, because I think 1 of them might be what you're looking for. 1) If your intention is to run mozilla embedded in a java application, then you can register the java component in java code. It sounds like this is what you've been able to do. This is done by installing a factory. This is my mozswing code... I don't know if any of it is specific to mozswing or is just javaxpcom (which mozswing is built on top of) ObjectFactory factory = new ObjectFactory(); // implements nsIFactory XPCOMUtils.register(myContractID, factory); // this calls nsIComponentRegistrar.registerFactory for me 2) What it sounds like you want to do, though, is register a java component without having to originally run mozilla in java. That is "independently" from java, as you put it. My understanding is that to do this, you need to use LiveConnect[1]. Read this page about 'Java in Firefox Extensions' [2]. The difference is that in 2) I don't think you have a single JVM. I think a JVM is created on demand and kept open for your extension. Other extensions might not use the same JVM. And if you ran mozilla embedded in Java, you would probably still create a new JVM. Not at all what I'm after. [1]https://developer.mozilla.org/en/LiveConnect [2]https://developer.mozilla.org/en/Java_in_Firefox_Extensions For reference, what I followed was the instructions in these 3 posts, but adapted it for Java. "Exposing XPCOM Components in Javascript" http://weblogs.mozillazine.org/weirdal/archives/017188.html http://weblogs.mozillazine.org/weirdal/archives/017202.html http://weblogs.mozillazine.org/weirdal/archives/017211.html If I didn't answer your question, please do clarify and I'll try to help.