Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

dealing with changing IIDs

32 views
Skip to first unread message

Grant Gayed

unread,
Feb 13, 2009, 5:12:42 PM2/13/09
to
Hi,

Eclipse embeds Mozilla via C++ (more precisely, Java calling C++ via JNI).
Mozilla versions 1.4 through xulrunner 1.9.0 are supported by compiling
against mozilla 1.4 (to satisfy a handful of C functions like
NS_GetComponentManager, NS_NewLocalFile, etc.), and by making all runtime
C++ calls directly via the object's method table (eg.- to invoke
QueryInterface on any object the function at method table index 0 is
invoked, AddRef is at method table index 1, etc.). This allows methods that
did not exist in mozilla 1.4 to be called if it is determined at runtime
that the user's mozilla/xulrunner version is new enough to contain the
method.

To do these direct vtable invocations, the shape of objects that methods are
invoked on needs to be known, so that the method at the correct table index
gets invoked. To determine this the interface IID is used to tell us what
to expect. For example, in one spot nsIHelperAppLauncher.Cancel() is
invoked with something like:

if
(aHelperAppLauncherDialogInstance.QueryInterface(nsIHelperAppLauncher_1.8IID
) == NS_OK) {
/* mozilla 1.8.0 */
nsIHelperAppLauncherInstance.invokeMethod(index3,
arg=NS_BINDING_ABORTED); // Cancel
} else {
/* mozilla pre-1.8 */
nsIHelperAppLauncherInstance.invokeMethod(index8, noArgs); // Cancel
}

Given this approach, is there any way to not be broken every time mozilla
IIDs change? It has become a ritual to look for broken interfaces between
major mozilla releases (eg.- 1.7 to 1.8), but it looks like we'll now be
broken in xulrunner 1.9.1 as well since nsIDocShell's IID has changed in the
1.9.1 beta stream. It's not a big deal to make a fix on our end that adds
the new IID to the collection of IIDs that are tried when an nsIDocShell is
needed, but it means that eclipse versions < 3.5 (3.5 to be released in
June) will be broken if xulrunner 1.9.1 is detected on the user's system.

Sorry for the long post, but I think our case is unusual for embeddors, so
it seemed worth explaining in more detail.

Grant


Boris Zbarsky

unread,
Feb 13, 2009, 8:12:03 PM2/13/09
to
> Given this approach, is there any way to not be broken every time mozilla
> IIDs change? It has become a ritual to look for broken interfaces between
> major mozilla releases (eg.- 1.7 to 1.8), but it looks like we'll now be
> broken in xulrunner 1.9.1 as well since nsIDocShell's IID has changed in the
> 1.9.1 beta stream. It's not a big deal to make a fix on our end that adds
> the new IID to the collection of IIDs that are tried when an nsIDocShell is
> needed, but it means that eclipse versions < 3.5 (3.5 to be released in
> June) will be broken if xulrunner 1.9.1 is detected on the user's system.
>
> Sorry for the long post, but I think our case is unusual for embeddors, so
> it seemed worth explaining in more detail.

Actually, I think your case is pretty similar to that of any other C++
embeddor: if you compile against a particular Gecko version but use
interfaces that change from that version to the next one, you end up
having to at least recompile to deal with the new version.

The only way I can think of offhand to deal with this is to stick to
frozen (de jure or de facto) interfaces. That's not always possible,
but it does reduce the pain...

Inthis case, might I ask what you needed to use nsIDocShell for?
Whatever it is, we should find a better way to expose it.

-Boris

Grant Gayed

unread,
Feb 17, 2009, 10:48:30 AM2/17/09
to
Hi Boris, thanks for the reply,

nsIDocShell.LoadStream() is used to set the Browser's content from a
client-provided string. Maybe there's another way of doing this? We use
many other unfrozen interfaces, but it would be nice for this one to go away
if possible.

I'll ask a follow-up question to my last one, much shorter this time. How
would a C++ app that's embedding mozilla (mozilla version unknown in
advance, it's whatever install is detected at runtime) do a QI for the
install's "current" implementation of an interface? So, something like a
dynamic version of
"nsIWebBrowserInstance.QueryInterface(nsIDocShell.NS_IDOCSHELL_IID)" where
NS_IDOCSHELL_IID is the IID of the nsIDocShell in the running mozilla, not
the one that was compiled against?

Grant


"Boris Zbarsky" <bzba...@mit.edu> wrote in message
news:2I2dnWS86u_5hwvU...@mozilla.org...

Boris Zbarsky

unread,
Feb 17, 2009, 11:53:16 AM2/17/09
to
Grant Gayed wrote:
> nsIDocShell.LoadStream() is used to set the Browser's content from a
> client-provided string. Maybe there's another way of doing this?

You could use a data: URI, no? That won't work for giving a particular
hostport to the data, though; do you need that to work?

> I'll ask a follow-up question to my last one, much shorter this time. How
> would a C++ app that's embedding mozilla (mozilla version unknown in
> advance, it's whatever install is detected at runtime) do a QI for the
> install's "current" implementation of an interface?

I don't think you can do that very easily... I suppose for scriptable
interfaces you could fetch the nsID via xpti or some such, like
XPConnect does it...

-Boris

Benjamin Smedberg

unread,
Feb 17, 2009, 2:02:31 PM2/17/09
to
On 2/17/09 10:48 AM, Grant Gayed wrote:

> nsIDocShell.LoadStream() is used to set the Browser's content from a
> client-provided string. Maybe there's another way of doing this? We use
> many other unfrozen interfaces, but it would be nice for this one to go away
> if possible.
>
> I'll ask a follow-up question to my last one, much shorter this time. How
> would a C++ app that's embedding mozilla (mozilla version unknown in
> advance, it's whatever install is detected at runtime) do a QI for the
> install's "current" implementation of an interface? So, something like a
> dynamic version of
> "nsIWebBrowserInstance.QueryInterface(nsIDocShell.NS_IDOCSHELL_IID)" where
> NS_IDOCSHELL_IID is the IID of the nsIDocShell in the running mozilla, not
> the one that was compiled against?

Let's look at the question slightly differently: if the C++ app were to ask
for whatever nsIDocShell is in th efuture, what could it then do with it? It
couldn't safely call any of the methods. Those method signature might have
changed, or their position in the vtable might have changed.

The only way you could be sure, forever into the future, that
nsIDocShell.LoadStream always has the same binary signature, is to use
nsIInterfaceInfo to actually check whether a method with that name exists,
and whether the signature is the same.

--BDS

dbradley

unread,
Feb 18, 2009, 8:56:53 AM2/18/09
to

Even if you determined that LoadStream existed with the same
signature, short of using XPTCall you're not going to be able to call
it, unless it happens to be in the same position in the vtable of the
interface.

You'd really need something akin to IDispatch. Bug 327689 -
nsIScriptableObject is where something like that is/was being done.
Seems to have stagnated, though.

David

Johnny Stenback

unread,
Feb 18, 2009, 6:36:04 PM2/18/09
to
The best way I can think of that will largely solve this general
problem, as long as the actual functions called don't change, is to make
all this code go through JS so that you eliminate the binary
dependencies and let XPConnect figure out where in the vtable the
function you're calling is etc, unless of course you want to write that
code yourself. Whether that's feasable in your particular case or not I
don't know...


--
jst

Jeff Walden

unread,
Feb 19, 2009, 2:31:51 AM2/19/09
to Benjamin Smedberg
On 17.2.09 11:02, Benjamin Smedberg wrote:
> Let's look at the question slightly differently: if the C++ app were to ask
> for whatever nsIDocShell is in th efuture, what could it then do with it? It
> couldn't safely call any of the methods. Those method signature might have
> changed, or their position in the vtable might have changed.
>
> The only way you could be sure, forever into the future, that
> nsIDocShell.LoadStream always has the same binary signature, is to use
> nsIInterfaceInfo to actually check whether a method with that name exists,
> and whether the signature is the same.

Moreso, as I understand it, even this is a false hope, because interface IDs don't just represent a vtable and method signatures, they represent the semantic behavior of the method as well. If the *way* in which a method is to be used changes, or if what it does changes (e.g. it starts throwing a new exception in specified use) the interface ID must still be changed, even tho the method signature and its index in the vtable might remain the same.

There really is no panacea here; you can only work with the interface versions you know about. That JS interactions with all this can get away with doing otherwise is due both to intermediary layers that prevent the sort of problems a C++-style mistake will cause and to "cheating" and assuming behaviors remain the same even when names and, in certain modes of interaction, interface names or IDs, change.

Jeff

Grant Gayed

unread,
Feb 19, 2009, 10:54:51 AM2/19/09
to
Thanks to everyone for your answers! It has confirmed for us that our case
is not particularly wrong/unusual.

It seems that the current approach of using GRE_GetGREPathWithProperties to
detect an available xulrunner to use is not ideal for us, since:

- many non-frozen mozilla interfaces are used (the non-frozen functionality
is needed)
- linux distros seem keen to always include the latest xulrunner versions,
including beta versions
-> this caused last-minute pain for eclipse's June 2008 release since
distros also switched from including xulrunner-1.9b5 to the newly-released
xulrunner-1.9 in June, which had a changed nsIDocShell IID
-> eclipse 3.4.1, which was released in September 2008, already won't
work[1] on a distro like rawhide since it has a 1.9.1-stream xulrunner with
a changed nsIDocShell IID

I'll investigate Boris' suggestion for removing the nsIDocShell dependency,
but this is only one example, there are many other non-frozen interfaces
that can break us by changing their IID.

I guess an alternative approach would be for eclipse to ship a xulrunner to
use, and given this information this will probably be considered. It just
seems unfortunate since the GRE_GetGREPathWithProperties mechanism exists,
and linux distros typically do provide a xulrunner (though given these
issues, can any app (excluding those that only use frozen interfaces)
actually make use of these distro-provided xulrunners for any length of
time?). Anyways, thanks again to everyone for your answers.

Grant

[1] "won't work" == "nsIDocShell interface won't be found" || "if an upper
version limit of < 1.9.1 had been specified for GRE_GetGREPathWithProperties
then no xulrunner would be found"


"dbradley" <dbra...@gmail.com> wrote in message
news:f96f4941-1943-47e5...@o11g2000yql.googlegroups.com...

Benjamin Smedberg

unread,
Feb 19, 2009, 10:59:54 AM2/19/09
to
On 2/19/09 10:54 AM, Grant Gayed wrote:

> I guess an alternative approach would be for eclipse to ship a xulrunner to
> use, and given this information this will probably be considered. It just
> seems unfortunate since the GRE_GetGREPathWithProperties mechanism exists,
> and linux distros typically do provide a xulrunner (though given these
> issues, can any app (excluding those that only use frozen interfaces)
> actually make use of these distro-provided xulrunners for any length of
> time?). Anyways, thanks again to everyone for your answers.

Embedding apps are strongly encouraged to use a maxversion and ask for
versions of XULRunner that they have been tested with. Therefore, if you've
tested Eclipse with XULRunner 1.8 -> 1.9 (but not 1.9.1), you should specify
a minversion of 1.8 and a maxversion of 1.9.0.*.

--BDS


Grant Gayed

unread,
Feb 19, 2009, 11:24:48 AM2/19/09
to
Yes, the maxversion was specified as 1.9.* because it was assumed (June
2008) that mozilla interfaces would not be changing during 1.9 [1], and as
such eclipse would not start failing to find xulrunners to use as soon as
linux distros began shipping 1.9.1-stream xulrunners (eight months later).
However since interfaces did change in 1.9.1, specifying a maxversion of
1.9.0.* would have been a little better since no browser is better than a
flaky one.

Either way, the hope is that an eclipse release does not have its browser
functionality break or "expire" within a few months of being shipped when
used on up-to-date linux distros, especially given the array of
eclipse-based apps that use slightly-old maintenance stream eclipse releases
for their better stability.

Grant

[1] I don't think mozilla interfaces have changed within previous major
releases, but I could be wrong, maybe they just haven't been in interfaces
used by us previously


"Benjamin Smedberg" <benj...@smedbergs.us> wrote in message
news:94ydnWfT0dtnHADU...@mozilla.org...

Benjamin Smedberg

unread,
Feb 19, 2009, 11:34:58 AM2/19/09
to
On 2/19/09 11:24 AM, Grant Gayed wrote:

> [1] I don't think mozilla interfaces have changed within previous major
> releases, but I could be wrong, maybe they just haven't been in interfaces
> used by us previously

We made an explicit promise not to change interfaces for 1.8.1. We made the
exact opposite promise for 1.9.1, acknowledging that we would be changing
interfaces.

The only reason upgrading a distro would break Eclipse is if it removed the
older major versions when it installed the newer ones. If Eclipse is part of
the distro packaging, I'd hope it could indicate which version of the
mozilla runtime it depends on.

If it's not part of the distro packaging, and you're providing separate
binary builds, I highly recommend shipping your own internal copy of
XULRunner as well... treating Mozilla as a system library is pain and hurt.

--BDS

Dan Mosedale

unread,
Feb 19, 2009, 2:08:32 PM2/19/09
to
On 2/18/09 11:31 PM, Jeff Walden wrote:
> On 17.2.09 11:02, Benjamin Smedberg wrote:
>> The only way you could be sure, forever into the future, that
>> nsIDocShell.LoadStream always has the same binary signature, is to use
>> nsIInterfaceInfo to actually check whether a method with that name
>> exists, and whether the signature is the same.
>
> Moreso, as I understand it, even this is a false hope, because interface
> IDs don't just represent a vtable and method signatures, they represent
> the semantic behavior of the method as well. If the *way* in which a
> method is to be used changes, or if what it does changes (e.g. it starts
> throwing a new exception in specified use) the interface ID must still
> be changed, even tho the method signature and its index in the vtable
> might remain the same.

It's even more subtle than that (and unfortunately in a non-helpful
way): the semantic meaning is actually spread out across IIDs, contract
IDs, and even CIDs. Almost none of this semantic meaning distribution
is delineated at all (or even documented). What little documentation
does exist is spread out across IDL files, .h files, MDC, Bugzilla, and
even newsgroup/email archives.

Dan

Wolfgang Rosenauer

unread,
Mar 15, 2009, 4:16:03 AM3/15/09
to
Benjamin Smedberg schrieb:

> The only reason upgrading a distro would break Eclipse is if it removed the
> older major versions when it installed the newer ones. If Eclipse is part of
> the distro packaging, I'd hope it could indicate which version of the
> mozilla runtime it depends on.

Just came across this issue when I tried to run Eclipse on openSUSE 11.1
(where I obviously have xulrunner 1.9.1b3 installed).

Speaking for openSUSE Eclipse is included and could require
mozilla-xulrunner190 (if maxversion would be correct). We usually keep
older xulrunners available if any shipped package still need it (and
it's at least a bit of upstream security supported still).
(Currently there are mozilla-xulrunner181 and mozilla-xulrunner190
officially available for openSUSE 11.1).

Actually the distributor should be mainly held responsible for keeping
Eclipse running. Eclipse should set the GRE range as safe as possible
though and the distributors should be aware of the requirements so they
could modify the required version if it works or keep it and be aware
that dropping a compatible version of xulrunner also will break Eclipse.
Eclipse should make sure to be compatible with the latest available
xulrunner with new releases so that distributors don't need to ship
older xulrunner that long (as security support is not quite long for
Mozilla browsers).


Wolfgang

0 new messages