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

> 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.
>

That's actually quite interesting. After a cursory look at the code it
looks very tough indeed to make resources available via the System class
loader when using eclipse.exe as the launcher takes over
java.lang.classpath. I'll verify and perhaps open an enhancement request.

> [...]
>
> 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.
>

Rather than creating a custom LogManager and setting the two properties
could you instead just use the default LogManager implementation and call
LogManager.readConfiguration(InputStream) using a file you located in an
Activator?

e.g. something like
public void start(BundleContext context) throws Exception {
      URL configAreaURL = new URL(context.getProperty(
"osgi.configuration.area"));
      File logConfig = new File(configAreaURL.getPath(),
"path.to.logConfig");
      LogManager.getLogManager().readConfiguration(new
FileInputStream(logConfig));
}

> > 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?
>
If you're using the TCCL approach to load the class then ContextFinder
should be sufficient. You shouldn't have to mess with anything else.

> [...]
>
> > 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)?
Yes. However unless you really need to you should just use a regular bundle
for this case. You'll need an Activator to run and fragments cannot have an
Activator.

>
> > 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).
>

Early during startup ContextFinder is set as the TCCL. All future threads
created by the framework inherit the same TCCL.
I suspect you were using ContextFinder and things started working when you
used osgi.parentClassloader=fwk. As you noted this is not the best way to
proceed.
I'm curious about what you're doing with hook configurators? I don't
believe it should be necessary for setting up your logging. Was this just
part of your experimenting or is it used elsewhere?

> > 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().
>
The critical piece when using the TCCL approach along with ContextFinder is
that your implementation of LogManager has to be visible to the bundle
where LogManager.readconfiguration is called.
e.g. either in the same bundle or visible via Import-Package etc.


> Is the assumption that ContextFinder is supposed to replace having to
> manually set the TCCL in cases like mine?
Yes, ContextFinder generally just works in most cases. If it doesn't work
we'd like to have a testcase understand why.

> 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?
Yes. Framework extension bundles work in Equinox.

> Would such exports be visible to the SystemClassLoader?
Generally not.
e.g. when launching with eclipse.exe your exports are not visible on the
SystemClassLoader. I'd have to verify however they might be visibile if you
launch with java -jar org.eclipse.osgi_xxx however this would be
coincidental and not something you should count on. In general the System
bundle and System class loader should be treated as distinct.

HTH
-Simon
>
> 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
>
> _______________________________________________
> equinox-dev mailing list
> equinox-dev@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/equinox-dev