アンマネージスレッドSpring Quartz Websphere Hibernate
-
05-07-2019 - |
質問
Quartz-JDBCJobStoreとSpring、Hibernate、およびWebsphereを使用した実装では、アンマネージスレッドがスローされているようです。
私はいくつかの記事を読んで、QuartzをSpringで使用するとその原因になると述べているIBMの技術記事を見つけました。彼らはCommnonJを使用してこの問題に対処することを提案しています。
さらに調査を行いましたが、これまで見てきた唯一の例は、データベースにない古いJobStoreの計画を扱っています。
だから、この問題の解決策の例が誰かあるのだろうかと思っていました。
ありがとう
解決
このための実用的なソリューションがあります(実際には2つ)。
1)クォーツソースコードを変更して、メインスケジューラスレッドにWorkManagerデーモンスレッドを使用します。動作しますが、クォートの変更が必要です。しかし、ハッキングされたクォーツのバージョンを維持したくないため、これを使用しませんでした。 (つまり、これをプロジェクトに提出するつもりでしたが、完全に忘れていました)
2)クォーツスレッドプールとして使用するWorkManagerThreadPoolを作成します。クォーツThreadPoolのインターフェイスを実装し、クォーツ内でトリガーされる各タスクがcommonj Workオブジェクトにラップされ、WorkManagerでスケジュールされるようにします。重要なのは、WorkManagerThreadPool内のWorkManagerは、スケジューラーを開始する前に、Java EEスレッドから(サーブレットの初期化など)初期化する必要があるということです。次に、WorkManagerThreadPoolは、新しいWorkオブジェクトを作成およびスケジュールすることにより、スケジュールされたすべてのタスクを処理するデーモンスレッドを作成する必要があります。この方法では、スケジューラー(独自のスレッド上)は管理対象スレッド(Workデーモン)にタスクを渡します。
単純ではありませんが、残念ながら、すぐに使用できるコードがありません。
他のヒント
この解決策を見つけたので、スレッドに別の答えを追加しました。
私の環境:WAS 8.5.5、Quartz 1.8.5、Springなし。
問題(<前述>アンマネージスレッドが ctx.lookup(myJndiUrl)
からNamingExceptionを引き起こし、代わりに他のアプリケーションサーバーで正常に動作していた( JBoss、Weblogic);実際、Webpshereは「インシデント」を発生させていました。次のメッセージが表示されます。
javax.naming.ConfigurationException:&quot; java:&quot;でのJNDI操作サーバーランタイムが操作のスレッドをJ2EEアプリケーションコンポーネントに関連付けることができないため、名前を完了できません。この条件は、JNDIクライアントが&quot; java:&quot;を使用しているときに発生する可能性があります。 nameは、サーバーアプリケーション要求のスレッドでは実行されません。 J2EEアプリケーションが&quot; java:&quot;でJNDI操作を実行しないことを確認してください。静的コードブロック内またはそのJ2EEアプリケーションによって作成されたスレッド内の名前。このようなコードは、サーバーアプリケーション要求のスレッドで必ずしも実行されるわけではないため、「java:」に対するJNDI操作ではサポートされていません。名前。
次の手順で問題を解決しました:
1)クォーツ1.8.6にアップグレード(コード変更なし)、maven pomのみ
2)は、新しいWorkManagerThreadExecutorを使用可能にするために、クラスパス(私の場合はEARの/ libフォルダー)に次の依存関係を追加しました
<dependency>
<groupId>org.quartz-scheduler</groupId>
<artifactId>quartz-commonj</artifactId>
<version>1.8.6</version>
</dependency>
注: QTZ-113 または公式のQuartzドキュメント 1.x 2.x この修正を有効にする方法については言及されていません。
3)以下をquartz.propertiesに追加しました(&quot; wm / default&quot;はWAS 8.5.5で既に構成されたDefaultWorkManagerのJNDIでした。リソース-&gt; AsynchronousBeansを参照) -&gt; WASコンソールのWorkManagers ):
org.quartz.threadExecutor.class=org.quartz.custom.WorkManagerThreadExecutor
org.quartz.threadExecutor.workManagerName=wm/default
注:正しいクラスは、quartz-scheduler-1.8.6(テスト済み)の org.quartz。 custom .WorkManagerThreadExecutor 、または org.quartz。< strong> commonj .WorkManagerThreadExecutor の 2.1.1 から(テストされていませんが、実際の Mavenのリポジトリにあるquartz-commonjのjar )
4)は、クォーツジョブの空のコンストラクターで JNDIルックアップを移動しました( m_klovreの「J2EEコンテナ外のスレッド」);つまり、コンストラクターは、アプリケーションのまったく同じJ2EEコンテキストからのリフレクション( newInstance()
メソッド)によって呼び出され、 java:global
名前空間にアクセスできましたが、 execute(JobExecutionContext)
メソッドはまだ貧弱なコンテキストで実行されていたため、アプリケーションのすべてのEJBが欠落していました
これがお役に立てば幸いです。
参考として、こちらで使用している上記のquartz.propertiesファイルの例
この記事を確認してください: http://www.ibm.com/developerworks/websphere/techjournal/ 0609_alcott / 0609_alcott.html
基本的に、コンテナ管理スレッドを使用するorg.springframework.scheduling.commonj.WorkManager TaskExecutorを使用するように、SchedulerFactoryBeanのtaskExecutorプロパティを設定します。
注:上記のQUARTZ-708のリンクはもう有効ではありません。 この新しい問題(新しいJiraの場合)は、問題に対処しているようです。 http://jira.terracotta.org/jira/browse/QTZ-113 (fixVersion = 1.8.6、2.0.2)
これについては、クォーツで作成された以下のJIRAリンクを確認できます。
http://jira.opensymphony.com/browse/QUARTZ-708
これには必要なWebSphereThreadPool実装があり、要件を満たすために前述のとおり、quartz.propertiesの変更で使用できます。これがお役に立てば幸いです。
よろしく、 シヴァ
websphereの管理対象スレッドプールを使用する必要があります。これは、springおよびcommonjを介して実行できます。 CommonJには、マネージスレッドを作成するタスクエグゼキューターを含めることができます。 jndiマネージスレッドリソースへの参照を使用することもできます。その後、commonjタスクエグゼキューターをSpringベースのQuartz SchedulerFactoryBeanに注入できます。
http://open.bekk.no/boss/springをご覧ください。 -scheduling-in-websphere / をスクロールして、「Quartz with CommonJ」にスクロールします。詳細については、セクションをご覧ください。
WAS85およびQuartz 1.8.6に対するPaoloCの提案は、WAS80(およびQuartz 1.8.6)でも機能し、Springは不要です。 (私の設定では、Spring 2.5.5は存在しますが、そのコンテキストでは使用されていません。)
そのようにして、InjectionHelperを使用して新しく作成されたすべてのジョブにCDIを適用し、独自のバリアントでSimpleJobFactoryをオーバーライドできました。インジェクションは、@ EJB(アノテーション付きEJBリモートビジネスインターフェースのJNDIルックアップ)と@Inject(最初に新しいInitialContextを使用し、次にこの新しくフェッチされたBMを使用してCDI Bean自体をルックアップするCDI BeanManagerのJNDIルックアップ)の両方で機能します。
PaoloC、その答えをありがとう! (このテキストがメイントピックへの回答としてではなく、「PaoloCへの回答」として表示されることを望みます。これらを区別する方法は見つかりませんでした。)
最近この問題に遭遇しました。実際に必要なのは:
- 作業をWebsphere Work Managerに委任することにより、スレッドプールを実装します。 (Quartzは、アンマネージスレッドでジョブを実行するSimpleThreadPoolのみを提供します)。
org.quartz.threadPool.class
プロパティ により、このスレッドプールを使用するようにquartzに指示します
-
org.quartz.threadExecutor.class
プロパティによって、WorkManagerThreadExecutor
を使用する(またはカスタムのものを実装する)ようにクォーツに伝える - 面倒なレガシーWebコンテナに少し我慢:)
こちらは github demo Websphere(およびTomcat)でQuartzを使用する方法。
誰かに役立つことを願っています。