It seems regretably, that there is no way to obtain IEclipseContext
without using injection.
There is written in an answer to How to use eclipse 4 DI in classes that are not attached to the application model:
The problem is, however, that the IEclipseContext
already needs to be
injected into a class that can access the object that needs injection.
Nevertheless I have already sorted out the problem of logging and I thing, the principle works generally. There is always some service providing things you need. If you cannot use the dependency injection, you've to get somehow (Internet and experiments are very often) an appropriate service class name. If you have got the service class name, then you can obtain an instance reference from the bundle context. Fortunately, the bundle context is accessible without using injection.
Back to our logging problem. The class being searched is org.osgi.service.log.LogService
:
public class Activator implements BundleActivator {
...
private static BundleContext context;
...
public static BundleContext getContext() {
return context;
}
...
public void start(BundleContext bundleContext) throws Exception {
ServiceReference<?> logser = bundleContext.getServiceReference(LogService.class);
LogService ls = (LogService)bundleContext.getService(logser);
//print an error to test it (note, that info can be below the threshold)
ls.log(LogService.LOG_ERROR, "The bundle is starting...");
Activator.context = bundleContext;
}
...
}
Et voilà!
!ENTRY eu.barbucha.rcp-experiment.kernel 4 0 2013-08-20 07:32:32.347
!MESSAGE The bundle is starting...
That's all. Later you can obtain the bundle context using Activator.getContext()
, if it would be needed.
Important note: Regretably you cannot decrease the threshold now. The JVM argument -Declipse.log.level
does not affect the OSGI log service and you're using just the OSGI logger now. Unfortunately they (may have provisionally) hardcoded the logging threshold (see How to log warnings and infos in eclipse 3.7). I found out, that they haven't repair it yet. Neither in the Kepler release. However you can make a compromise. You can do that injection-way, where possible.
Final solution (to catch exceptions globally as well)
I extended my activator:
ServiceReference<?> logreser = bundleContext.getServiceReference(LogReaderService.class);
LogReaderService lrs = (LogReaderService) bundleContext.getService(logreser);
lrs.addLogListener(new LogListener() {
@Override
public void logged(LogEntry entry) {
System.err.println("Something was logged: " + entry.getMessage());
}
});
The text beginning with Something was logged really appears, whenewer is something somewhere logged. But the very advantage is, that this class is mine. I can control it. The log entry contains also the level. I can also easily set the threshold. For example on the command line.
org.eclipse.e4.core.services.Logger
class int this specializedIEclipseContext
, how mentioned on this wiki page. If I understand good, it can neither be. There is just the OSGI logger for these low-level things like activators and so on. – Strontian