[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[equinox-dev] Re: Recipe to get extension bundle classes on the class path

Simon Kaegi <Simon_Kaegi@xxxxxxxxxx> writes:

> If you're writing a custom LogManager I'd definitely suggest placing
> the code for your implementation on the classpath. e.g.
> SystemClassLoader.

As I've been trying to move toward using the Equinox launcher to start
up the framework, with the launcher JAR or the native "eclipse.exe"
executable being the user's means of starting the program, I'm not sure
how to put any of my classes on the class path as seen by
SystemClassLoader.

[...]

I'm not trying to replace the LogManager; I'm just trying to provide an
initializer class for the logging configuration. It would be easy enough
to just specify the java.util.logging.config.file property in my
config.ini, but two problems arise:

o Specifying an absolute path is difficult, as I don't know where my
  program will be installed on the user's disk.

o Specifying a relative path doesn't work either, as the path is taken
  to be relative to whatever the current working directory was of the
  process that started the program.

As my intention is to find my logging.properties in some location
relative to the application's installation directory ("configuration
area" in Equinox terms), I need to use a logging initializer class --
specified via the java.util.logging.config.class property -- to figure
out this location at run time.

> In this case your logging initializer would still have to call
> LogManager.readConfiguration(...) to load your settings from the
> config area.

Right. The problem is how to make my initializer class available to
either of the two class loaders tried by LogManager.readConfiguration(),
which are the SystemClassLoader and the Thread Context Class Loader.

> That said, if you're in full control of your system and willing to
> live with the consequences you should be able to set the LogManager
> via the TCCL.

I did find that if I could get the framework to call into the bundle
hosting my logging initializer class -- either by way of
Activator.start() or in a hook configurator's addHooks() method -- I
could manually set the TCCL to the current class loader and force the
logging system to initialize. In that case, my class is available,
because I've forced it to be so.

But consider all of these interacting entities:

o Framework extension bundles
  (Fragment-Host: system.bundle; extension:=framework)

o org.osgi.framework.system.packages property

o osgi.(frameworkP|p)arentClassloader property

o ContextFinder

Shouldn't one or more of these address this problem?

[...]

> ContextFinder will load classes from the first bundle on the stack
> which should be your bundle that holds the implementation so it should
> just work.

Does this apply to fragment bundles as well (specifically framework
extension bundles)? 

> If it doesn't I suspect that you'll have to carefully debug/walk the
> LogManager static initializer to see what's going on.

I spent many hours doing just that. I never saw ContextFinder enter the
picture (or, rather, the debugger), but when I started fiddling with the
osgi.parentClassloader property I found certain settings that would make
my class visible to one of the two class loaders in question -- I can't
remember which now. However, as I wrote earlier¹, setting
osgi.parentClassloader achieved one goal while compromising another: it
interfered with the launcher's normal class path assembly to put
extension bundles on the startup class path (so that hook configurators'
hookconfigurators.properties files can be found).

> Do either of these approaches work for you? Am I missing something?

I think I've tried one of them (relying on ContextFinder) and it didn't
work in a way that satisfied LogManager.readConfiguration().

Is the assumption that ContextFinder is supposed to replace having to
manually set the TCCL in cases like mine? And what about Section
3.15.1's promise that one can get packages to be exported by the System
Bundle with an extension bundle? Is that supposed to work in Equinox?
Would such exports be visible to the SystemClassLoader?

I appreciate you writing back in detail. It's been hard to summon any
replies on this topic. My own confusion makes it hard to ask simple
questions.


Footnotes: 
¹ http://article.gmane.org/gmane.comp.ide.eclipse.equinox.devel/1747

-- 
Steven E. Harris