问题
I've been banging my head a against this particular brick wall now for more than two days. I am attempting to create an XPCOM service for use in a Firefox extension but am unable to initialise the component with the following error displayed in the error console in Firefox.
Timestamp: 07/06/2012 09:23:28 Error: uncaught exception: [Exception...
"Component returned failure code: 0x80570016 (NS_ERROR_XPC_GS_RETURNED_FAILURE)
[nsIJSCID.getService]" nsresult: "0x80570016 (NS_ERROR_XPC_GS_RETURNED_FAILURE)"
location: "JS frame :: chrome://logger/content/logger.js :: <TOP_LEVEL> :: line 21"
data: no]
I have reduced the component to the bare minimum using the excellent boilerplate generator at ted.mielczarek.org. The component code is as follows...
const nsISupports = Components.interfaces.nsISupports;
const CLASS_ID = Components.ID("808e1607-caea-418c-b563-d9fe1df6ee08");
const CLASS_NAME = "Test component";
const CONTRACT_ID = "@test/loggerservice;1";
function LoggerService() {
this.wrappedJSObject = this;
}
LoggerService.prototype = {
QueryInterface: function(aIID)
{
if (!aIID.equals(nsISupports))
throw Components.results.NS_ERROR_NO_INTERFACE;
return this;
}
}
The remainder of the boilerplate that creates the module and factory interfaces is unchanged.
The chrome.manifest file looks like this...
content logger chrome/content/
skin logger classic/1.0 chrome/skin/
locale logger en-US chrome/locale/en-US/
component {808e1607-caea-418c-b563-d9fe1df6ee08} components/loggerservice.js
contract @test/loggerservice;1 {808e1607-caea-418c-b563-d9fe1df6ee08}
overlay chrome://browser/content/browser.xul chrome://logger/content/logger-overlay.xul
style chrome://global/content/customizeToolbar.xul chrome://logger/skin/overlay.css
Finally, the logger-overlay.xul
file includes a script file - logger.js
- which attempts to get a reference to the LoggerService
component using the following code...
this.loggerService = Components.classes["@test/logger;1"].getService().wrappedJSObject;
and it is this line that is reporting in the firefox error console.
I can't see how much simpler I can make it - any insight would be very much appreciated.
回答1:
This is a nice boilerplate generator but unfortunately an outdated one. For one, you should be using XPCOMUtils, this will get rid of most of the boilerplate. More importantly, this boilerplace generator hasn't been updated to XPCOM changes in Gecko 2.0 and defines NSGetModule
function instead of NSGetFactory
. Module code like this should work however:
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
function LoggerService() {
this.wrappedJSObject = this;
}
LoggerService.prototype = {
classID: Components.ID("808e1607-caea-418c-b563-d9fe1df6ee08"),
classDescription: "Test component",
contractID: "@test/loggerservice;1",
QueryInterface: XPCOMUtils.generateQI([])
}
if ("generateNSGetFactory" in XPCOMUtils)
var NSGetFactory = XPCOMUtils.generateNSGetFactory([LoggerService]); // 2.0+
else
var NSGetModule = XPCOMUtils.generateNSGetModule([LoggerService]); // 1.9.x
You can remove the NSGetModule
code if your extension doesn't need to be compatible with Firefox 3.6. You can also remove the classDescription
and contractID
properties then, these are specified in chrome.manifest
already.
Note: If you only need an object that will stay around for the entire browsing session and can be accessed from anywhere then a JavaScript code module would be a better choice - no XPCOM boilerplate and no wrappedJSObject
hacks.
来源:https://stackoverflow.com/questions/10928864/cant-create-javascript-xpcom-service-for-firefox-extension