1

クライアントコンポーネントが「管理された」環境で(Adobe InDesignプラグインとして)実行されるアプリケーションがあります。この「管理された」環境では、実行中にスレッドを作成することはできないようですが、アプリケーションの起動時にのみ作成できます。

このクライアントコンポーネントは、JNDIおよびRMI / IIOPを介してGlassfishサーバーに接続し、すべてが完全に機能するさまざまなEJBメソッド呼び出しを実行します(ここでは重要ではない面倒なCORBAシリアル化の問題を除く)。また、JMSを使用して接続し、トピックの読み取りを実行したいと思います。これらのトピックの読み取りを実行するために使用するコードは、すでに単体テスト中であり、開始してトピックを読み取り、必要な統合を実行できることを確認しています(これは単体テストよりも統合テストですが、アプリケーションを確認する必要があります通信層、いいえ?)。このコードは、単体テストで実行すると完全に機能します。残念ながら、クライアントコンポーネント(Indesignに埋め込まれていて、スレッドを作成する機能がない)から実行するとNullPointerException、次のように失敗します。

29 mai 2012 18:07:22 com.sun.enterprise.connectors.ActiveRAFactory getActiveRA
INFO: Deployed RAR [ jmsra ] has inbound artifacts, but the runtime does not support it. Providing only outbound support 
29 mai 2012 18:07:22 org.hibernate.validator.util.Version <clinit>
INFO: Hibernate Validator 4.2.0.Final
29 mai 2012 18:07:24 com.sun.messaging.jms.ra.ResourceAdapter start
INFO: MQJMSRA_RA1101: GlassFish MQ JMS Resource Adapter: Version:  4.5  (Build 29-b) Compile:  Wed Feb  9 22:53:30 PST 2011
29 mai 2012 18:07:24 com.sun.messaging.jms.ra.ResourceAdapter start
INFO: MQJMSRA_RA1101: GlassFish MQ JMS Resource Adapter starting: broker is EMBEDDED, connection mode is Direct
29 mai 2012 18:12:58 com.sun.messaging.jms.blc.LifecycleManagedBroker start
GRAVE: MQJMSRA_RA4001: start:Aborting:Exception starting EMBEDDED broker=java.lang.NullPointerException
29 mai 2012 18:12:58 com.sun.messaging.jms.blc.LifecycleManagedBroker start
INFO: SJSMQ LifecycleManagedBroker configuration=
    brokerInstanceName       =imqbroker
    brokerBindAddress        =null
    brokerPort               =7676
    brokerHomeDir            =C:\Java-ext\glassfish3\mq
    brokerLibDir             =C:\Java-ext\glassfish3\mq\lib
    brokerVarDir             =C:\Java-ext\glassfish3\glassfish\domains\autocat\imq
    brokerJavaDir            =C:\Program Files\Java\jdk1.6.0_30\jre
    brokerArgs               =null
    MasterBroker             =null
    brokerId                 =null
    adminUsername            =admin
    adminPassword            =<default>
    adminPassFile            =null
    ConnectionURL            =mq://localhost:7676/
    dbType                   =null
    dbProps                  ={}
    dsProps                  ={}
    useJNDIRmiServiceURL     =true
    useSSLJMXConnector       =true
    brokerEnableHA           =false
    clusterId                =null
    rmiRegistryPort          =7776
    startRmiRegistry         =true
    brokerStartTimeout       =  jmxServiceURL            =null
60000

29 mai 2012 18:12:58 com.sun.enterprise.connectors.ActiveOutboundResourceAdapter init
GRAVE: RAR6035 : Resource adapter start failed. 
javax.resource.spi.ResourceAdapterInternalException: MQJMSRA_RA4001: start:Aborting:Exception starting EMBEDDED broker=java.lang.NullPointerException
    at com.sun.messaging.jms.blc.LifecycleManagedBroker.start(LifecycleManagedBroker.java:458)
    at com.sun.messaging.jms.ra.ResourceAdapter.start(ResourceAdapter.java:380)
    at com.sun.enterprise.connectors.ActiveOutboundResourceAdapter.startResourceAdapter(ActiveOutboundResourceAdapter.java:182)
    at com.sun.enterprise.connectors.ActiveOutboundResourceAdapter.init(ActiveOutboundResourceAdapter.java:129)
    at com.sun.enterprise.connectors.ActiveRAFactory.instantiateActiveResourceAdapter(ActiveRAFactory.java:135)
    at com.sun.enterprise.connectors.ActiveRAFactory.createActiveResourceAdapter(ActiveRAFactory.java:106)
    at com.sun.enterprise.connectors.service.ResourceAdapterAdminServiceImpl.createActiveResourceAdapter(ResourceAdapterAdminServiceImpl.java:212)
    at com.sun.enterprise.connectors.ConnectorRuntime.createActiveResourceAdapter(ConnectorRuntime.java:379)
    at com.sun.enterprise.resource.naming.AdministeredObjectFactory.getObjectInstance(AdministeredObjectFactory.java:107)
    at javax.naming.spi.NamingManager.getObjectInstance(Unknown Source)
    at com.sun.enterprise.naming.impl.SerialContext.getObjectInstance(SerialContext.java:556)
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:514)
    at com.sun.enterprise.naming.impl.SerialContext.lookup(SerialContext.java:455)
    at javax.naming.InitialContext.lookup(Unknown Source)
    at fr.perigee.autocat.indesign.remoting.jndi.jms.AdapterJMSListener.getConsumer(AdapterJMSListener.java:261)
    at fr.perigee.autocat.indesign.remoting.jndi.jms.AdapterJMSListener$AdapterJMSListenerRunnable.run(AdapterJMSListener.java:50)
    at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
    at java.util.concurrent.FutureTask$Sync.innerRunAndReset(Unknown Source)
    at java.util.concurrent.FutureTask.runAndReset(Unknown Source)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$101(Unknown Source)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.runPeriodic(Unknown Source)
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.RuntimeException: java.lang.NullPointerException
    at com.sun.messaging.jmq.jmsclient.runtime.impl.BrokerInstanceImpl.start(BrokerInstanceImpl.java:211)
    at com.sun.messaging.jms.blc.EmbeddedBrokerRunner.start(EmbeddedBrokerRunner.java:331)
    at com.sun.messaging.jms.blc.LifecycleManagedBroker.start(LifecycleManagedBroker.java:454)
    ... 24 more
Caused by: java.lang.NullPointerException
    at com.sun.messaging.jmq.jmsserver.data.TransactionList.<init>(TransactionList.java:182)
    at com.sun.messaging.jmq.jmsserver.Broker._start(Broker.java:1170)
    at com.sun.messaging.jmq.jmsserver.Broker.start(Broker.java:456)
    at com.sun.messaging.jmq.jmsserver.BrokerProcess.start(BrokerProcess.java:164)
    at com.sun.messaging.jmq.jmsserver.DirectBrokerProcess.start(DirectBrokerProcess.java:92)
    at com.sun.messaging.jmq.jmsclient.runtime.impl.BrokerInstanceImpl.start(BrokerInstanceImpl.java:206)
    ... 26 more

私がこれまでに発見したことから、クライアントコードはJMSサーバーへの接続(への接続mq://localhost://7676)を取得しますが、TransactionListの開始に失敗します。コンパイルされていないソースコード(Jadに感謝します!)は、そこで失敗することを示しています:

    /* 182*/Globals.getClusterManager().addEventListener(((ClusterListener) (this)));

org.glassfish.enterprise.iiop.util.S1ASThreadPoolManagerそれをデバッグしようとすると、同じようにスレッドを作成できないために、クライアントを起動できないこともわかりました。

どこかに何か問題があると思いますが、何ですか?知らない。

では、Glassfishクライアント環境に、スレッドが独自のスレッドプールを作成しようとして無残に失敗するのではなく、(アプリケーションの起動時に作成された)個人のスレッドプールからのみ取得できることをどのように伝えることができますか?

4

1 に答える 1

1

短縮版

Glassfishのjms-core.jarを忘れてmavenを使用してアプリケーションをデプロイしました。これは、 gf-client-module.jarの実行時の依存関係であり、Mavenビルドはコンパイルの依存関係のみをコピーしたためです。Mavenビルドを修正すると、問題が修正されました。

ロングバージョン

ロングバージョンは、恐怖、涙、そして血の物語です。

そのclusterManagerはどのようにしてnullになりましたか?

最初は、ClusterManagerに関連付けられたTransactionListに問題があったため、com.sun.messaging.jmq.jmsserver.Globalsコードがどのように初期化されたかを調べようとしました。Globals#initCLusterManager(MQAddress)さまざまなクラスパラメータ(Propertiesオブジェクトを含む)を使用して、アプリケーションで使用されるClusterManagerをロードする、適切に呼び出されたメソッドであることがわかりました。何 ?ClusterManager?クライアントコードでは?それは一体何ですか(これについては後で詳しく説明します)。

とにかく、そのClusterManagerはロードされましたが、後でnullに設定されました(主にクラスター構成でのループバックアドレスの使用が原因です-もう一度、JMSクライアントでは信じられないほど奇妙です)...したがって、初期化された方法を確認することは明らかに正しいパスではありませんでしたバグ解決に、それは私を困惑させました。

テストに合格したが、本番コードにはまだバグがある場合はどうすればよいですか?

私が質問したように、私は(私の理解では)まったく同じことをするテストを持っています。テストは常に成功し、生産は常に失敗します。だから、そこには何か違うものがあるはずですよね?

だから私は私に何か新しいことをしました:私はそのGlobals#initClusterManagerコードにブレークポイントを置き、コード:本番とテストの両方を使用してそれに到達しようとしました。ご想像のとおり、prodではブレークポイントに到達しましたが、testでは到達しませんでした。そこで、ブレークポイントに到達することがすでにわかっている場所にブレークポイントを移動しました:ActiveRAFactory#getActiveRA(ConnectorDescriptor, String)...(ああ、いや、そこには配置しませんでしたが、そのブレークポイントを配置した場所から、実行パスがどこになるかがわかりました。そのメソッド呼び出しが異なっていたので、最終的にブレークポイントをそこに置きました)。

そのブレークポイントで、私はすぐに何か奇妙なことに気づきました:への呼び出し

    Collection<ActiveResourceAdapter> activeRAs =  activeRAHabitat.getAllByContract(ActiveResourceAdapter.class);

テスト中または本番環境にあるという事実に応じて、異なる結果が返されました。テストではリストに4つの要素(を含むActiveJmsResourceAdapter)がありましたが、本番環境では3つしかありませんでした。

ResourceAdapterは異なりますが、なぜですか?

それから私は戸惑いました:それから私はまだ知らなかったIoCコンテナである以外の理由でGlassfish HK2を非難する傾向がありました...私は間違っていたことがわかりました、ああとても間違っていました!

啓示はEclipseデバッガーの式の評価から来ました:私は式として入力しました

com.sun.enterprise.connectors.jms.system.ActiveJmsResourceAdapter.class

そして、私が得たのはClassNotFoundExceptionだけでした...待って... ClassNotFoundException?そして、このクラスはjms-core.jar?jarが本番フォルダにあると確信しています。... いいえ ?いいえ

なんてこった!

そのフォルダー内のjarをコピーするために使用するmaven -dependency-pluginは、「コンパイル」するように構成されたincludeScopeでcopy-dependenciesを使用することが判明しました。

簡単な解決策でクレイジーバグ

そこで、コピー依存関係に別の実行を追加し、incldueScope "runtime"に構成すると、すべて正常に機能しました。

于 2012-06-01T07:31:35.753 に答える