2013-08-19 10 views
5

Ich habe ein Problem mit einer Eclipse 4 RCP-Anwendung stecken. Ich muss einige Ereignisse protokollieren. Ich brauche irgendwie einen Hinweis auf den Logger. Ich weiß, wie man das mit IEclipseContext macht, aber ich habe nirgends gefunden, wie man IEclipseContext ohne die Abhängigkeitsinjektion erhält, die ich nicht im Aktivator verwenden kann. Weißt du irgendjemand, wie man das Problem lösen kann, bitte?Wie bekomme ich den IEclipseContext in einem Aktivator

Vielen Dank

Antwort

2

Es scheint bedauerlicherweise, dass es keine Möglichkeit gibt IEclipseContext zu erhalten, ohne Injektion verwendet wird. Es wird in einer Antwort auf How to use eclipse 4 DI in classes that are not attached to the application model geschrieben:

Das Problem ist jedoch, dass die IEclipseContext bereits in eine Klasse eingespritzt werden muss, dass das Objekt, das Einspritzung benötigt zugreifen kann.

Trotzdem habe ich schon das Problem der Protokollierung aussortiert und ich weiß, das Prinzip funktioniert generell. Es gibt immer einen Service, der Dinge zur Verfügung stellt, die Sie brauchen. Wenn Sie die Abhängigkeitsinjektion nicht verwenden können, müssen Sie irgendwie (Internet und Experimente sind sehr oft) einen geeigneten Dienstklassennamen erhalten. Wenn Sie den Namen der Serviceklasse erhalten haben, können Sie eine Instanzreferenz aus dem Bündelkontext abrufen. Glücklicherweise ist der Bundle-Kontext ohne Verwendung einer Injektion zugänglich.

Zurück zu unserem Protokollierungsproblem. Die Klasse gesucht wird, ist 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... 

Das ist alles. Später können Sie den Bündelkontext unter Verwendung von Activator.getContext() abrufen, falls dies erforderlich sein sollte.

Wichtiger Hinweis: Leider können Sie den Schwellenwert jetzt nicht verringern. Das JVM-Argument -Declipse.log.level hat keine Auswirkungen auf den OSGI-Protokolldienst und Sie verwenden jetzt nur den OSGI-Protokollierer. Leider haben sie (möglicherweise provisorisch) den Logging-Schwellenwert fest programmiert (siehe How to log warnings and infos in eclipse 3.7). Ich habe herausgefunden, dass sie es noch nicht repariert haben. Weder in der Kepler-Veröffentlichung. Sie können jedoch einen Kompromiss eingehen. Sie können das tun, injection-way, wenn möglich.

Endlösung (Ausnahmen global als auch zu fangen)

ich meine Aktivator erweitert:

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()); 
    } 
}); 

Der Text beginnt mit Etwas wirklich angemeldet wurde erscheint, whenewer ist etwas irgendwo angemeldet. Aber der große Vorteil ist, dass diese Klasse meine ist. Ich kann es kontrollieren. Der Protokolleintrag enthält auch die Ebene. Ich kann die Schwelle auch leicht einstellen. Zum Beispiel in der Befehlszeile.

5

Sie können eine spezialisierte IEclipseContext erhalten, indem Sie EclipseContextFactory.getServiceContext(bundleContext) aufrufen, die den Zugriff auf OSGi-Dienste ermöglicht.

+0

Was bedeutet die _specialized_ eigentlich bedeuten? Ich habe es versucht, aber es gibt keine solche Instanz der 'org.eclipse.e4.core.services.Logger' Klasse in diesem spezialisierten 'IEclipseContext', wie erwähnt [auf dieser Wiki Seite] (http: //wiki.eclipse. org/E4/EAS/Logging_und_Tracing). Wenn ich gut verstehe, kann es auch nicht sein. Es gibt nur den OSGI Logger für diese Low-Level-Dinge wie Aktivatoren und so weiter. –

+0

Es ist "spezialisiert", weil es nur OSGi-Dienste enthält, nicht andere Dinge, die normalerweise im Kontext gefunden werden. Es enthält LogService und LogReaderService –

+0

Ja, Sie haben Recht. Es gibt nur die OSGI-Dienste, weil der Aktivator eine Angelegenheit der OSGI-Ebene ist. –

2

Es ist möglich, den "WorkbenchContext" aus den IWorkbench als Service zu erhalten:

import org.eclipse.e4.core.contexts.IEclipseContext; 
import org.eclipse.ui.PlatformUI; 

public final class EclipseContextHelper { 

    public static IEclipseContext getActiveContext(){ 
     IEclipseContext context = getWorkbenchContext(); 
     return context == null ? null : context.getActiveLeaf(); 
    } 

    public static IEclipseContext getWorkbenchContext(){ 
     return PlatformUI.getWorkbench().getService(IEclipseContext.class); 
    } 
} 
+0

PlatformUI.getWorkbench() ist RCP 3 API. – aviit

Verwandte Themen