2017-08-25 7 views
1

は私がサービスを定義するモジュールを書いた2つのインスタンスが

public class ServiceActivator implements BundleActivator { 

    private ServiceRegistration registration; 

    @Override 
    public void start(BundleContext context) throws Exception { 
     registration = context.registerService(TranslationService.class.getName(), new TranslationServiceImpl(), null); 
    } 

    [...] 
} 

...サービスを使用するモジュール:

01私は(ゴーゴーシェル経由)スタート
@Component(
    immediate = true, 
    configurationPid = [...] 
    service = Portlet.class 
) 
public class TranslationPortlet extends MVCPortlet { 

    @Reference(unbind = "-") 
    protected void setTranslationService(TranslationService translationService) { 
     log.info("Using " + translationService.getClass().getName() 
       + " " + System.identityHashCode(translationService)); 
     this.translationService = translationService; 
    } 

    private TranslationService translationService; 
} 

ログイン

ログAPIと実装モジュール:私は(ゴーゴーシェル経由)開始後

Constructor my.TranslationServiceImpl 606817095 
Service registered. 
STARTED my.impl_1.0.0 [538] 
Constructor my.TranslationServiceImpl 362465287 
Configuring my.TranslationServiceImpl 362465287 

使用して、モジュール:

STARTED my.app_1.0.0 [558] 
Using my.TranslationServiceImpl 606817095 

質問

なぜ2つのインスタンスが使用されていますか?
すべてのモジュールでサービス実装の同じインスタンスを使用する方法を教えてください。その後

my.TranslationServiceImpl.<init>(TranslationServiceImpl.java:56) 
my.ServiceActivator.start(ServiceActivator.java:24) 
org.eclipse.osgi.internal.framework.BundleContextImpl$3.run(BundleContextImpl.java:774) 
org.eclipse.osgi.internal.framework.BundleContextImpl$3.run(BundleContextImpl.java:1) 
java.security.AccessController.doPrivileged(Native Method) 
org.eclipse.osgi.internal.framework.BundleContextImpl.startActivator(BundleContextImpl.java:767) 
org.eclipse.osgi.internal.framework.BundleContextImpl.start(BundleContextImpl.java:724) 
org.eclipse.osgi.internal.framework.EquinoxBundle.startWorker0(EquinoxBundle.java:951) 
org.eclipse.osgi.internal.framework.EquinoxBundle$EquinoxModule.startWorker(EquinoxBundle.java:328) 
org.eclipse.osgi.container.Module.doStart(Module.java:566) 
org.eclipse.osgi.container.Module.start(Module.java:434) 
org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:402) 
org.apache.felix.gogo.command.Basic.start(Basic.java:729) 
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
java.lang.reflect.Method.invoke(Method.java:498) 
org.apache.felix.gogo.runtime.Reflective.invoke(Reflective.java:137) 

詳細な実装のコンストラクタが呼び出された2回の

スタックトレースを

my.TranslationServiceImpl.<init>(TranslationServiceImpl.java:56) 
sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) 
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) 
java.lang.reflect.Constructor.newInstance(Constructor.java:423) 
java.lang.Class.newInstance(Class.java:442) 
org.apache.felix.scr.impl.manager.SingleComponentManager.createImplementationObject(SingleComponentManager.java:236) 
org.apache.felix.scr.impl.manager.SingleComponentManager.createComponent(SingleComponentManager.java:108) 
org.apache.felix.scr.impl.manager.SingleComponentManager.getService(SingleComponentManager.java:906) 
org.apache.felix.scr.impl.manager.SingleComponentManager.getServiceInternal(SingleComponentManager.java:879) 
org.apache.felix.scr.impl.manager.AbstractComponentManager.activateInternal(AbstractComponentManager.java:748) 
org.apache.felix.scr.impl.manager.AbstractComponentManager.enableInternal(AbstractComponentManager.java:674) 
org.apache.felix.scr.impl.manager.AbstractComponentManager.enable(AbstractComponentManager.java:429) 
org.apache.felix.scr.impl.manager.ConfigurableComponentHolder.enableComponents(ConfigurableComponentHolder.java:657) 
org.apache.felix.scr.impl.BundleComponentActivator.initialEnable(BundleComponentActivator.java:341) 
org.apache.felix.scr.impl.Activator.loadComponents(Activator.java:403) 
org.apache.felix.scr.impl.Activator.access$200(Activator.java:54) 
org.apache.felix.scr.impl.Activator$ScrExtension.start(Activator.java:278) 
org.apache.felix.utils.extender.AbstractExtender.createExtension(AbstractExtender.java:259) 
org.apache.felix.utils.extender.AbstractExtender.modifiedBundle(AbstractExtender.java:232) 
org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:482) 
org.osgi.util.tracker.BundleTracker$Tracked.customizerModified(BundleTracker.java:1) 
org.osgi.util.tracker.AbstractTracked.track(AbstractTracked.java:232) 
org.osgi.util.tracker.BundleTracker$Tracked.bundleChanged(BundleTracker.java:444) 
org.eclipse.osgi.internal.framework.BundleContextImpl.dispatchEvent(BundleContextImpl.java:905) 
org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) 
org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) 
org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEventPrivileged(EquinoxEventPublisher.java:165) 
org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEvent(EquinoxEventPublisher.java:75) 
org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEvent(EquinoxEventPublisher.java:67) 
org.eclipse.osgi.internal.framework.EquinoxContainerAdaptor.publishModuleEvent(EquinoxContainerAdaptor.java:102) 
org.eclipse.osgi.container.Module.publishEvent(Module.java:461) 
org.eclipse.osgi.container.Module.start(Module.java:452) 
org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:402) 
org.apache.felix.gogo.command.Basic.start(Basic.java:729) 
sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
java.lang.reflect.Method.invoke(Method.java:498) 
org.apache.felix.gogo.runtime.Reflective.invoke(Reflective.java:137) 

私はサービスの活性化因子で実装をインスタンス化してはならないようなので、その思えます?それはthis tutorialでもやっているようです。

+0

これは不可能です。 "my.TranslationServiceImpl 1451438505の設定"という行が表示されますか? –

+0

コンストラクタロギングで再確認できますか? –

+0

@NeilBartlett:詳細とコンストラクタロギングを追加しました。また、私のサービスアクティベータがおそらく問題を引き起こしていることに気付きましたが、私はそれをどのように変更するか分かりません。どうもありがとう! –

答えて

3

明示的にコンポーネントを作成しているため、コンポーネントの2番目のインスタンスが取得されています(行24のServiceActivator.java)。これは、あなたが投稿した最初のスタックトレースによって明らかになります。

コードの行を削除するだけで、すべて正常です。

実際、ServiceActivatorはまったく必要ありません。あなたのバンドルにはBundleActivatorだと思いますか? DSを使用するときにアクティベータを書く必要はありません。なぜなら、アクティベータでできることはDSコンポーネントなどで行うことができるからです。実際、私の一般的な推奨はバンドルアクチベータを書くことではありません。

+0

私はServiceActivator.javaのコードを投稿したという事実を忘れました。あなたは間違いなくそれを必要としません。ただそれを削除します。 –

2

ニールは答えを見つけた、私はちょうどいくつかの詳細を追加してみましょう:ニールが言ったように

は、サービスの活性化剤は、私は私の質問ににリンクされているチュートリアルを示唆して何にもかかわらず、必要とされていません。ただそれを削除します。

また、Bundle-Activator:行もbnd.bndから削除してください。そうしないと、展開時にBundle-Activator not found on the bundle class path nor in importsエラーが発生します。

サービスアクティベータの代わりに、Neil氏が話している「DS」を使用してください。これは宣言型サービスを意味し、アノテーションを処理するOSGiテクノロジーです。これを使用するには、実装クラスの@Componentアノテーションにservice =命令を追加し、実装されたサービス(API)のインタフェースを値として追加します。例:

@Component(
    service = TranslationService.class, 
    immediate = true, 
    configurationPid = "my.TranslationConfiguration" 
) 
public class TranslationServiceImpl implements TranslationService { 
+1

ねえ、私はあなたがリンクしたチュートリアルを読んで、それはとてもよく見えません。私たちがOSGiに持っている問題の1つは、率直に教えようとする前にもっと勉強する必要がある人が書いた100万のチュートリアルがあるということです。しかし、初心者の方は、どのチュートリアルが良いのか、どれが迷惑であるのかを知ることは難しいです。 FWIW「proliferay.com」サイトはLiferayと何ら関係がなく、おそらく商標権を侵害しているとは思わない。 –

関連する問題