Hatena::ブログ(Diary)

達人プログラマーを目指して このページをアンテナに追加 RSSフィード

2011-05-06

JBoss AS5.1上でJPAを完全にSpring駆動で実行させる方法

JPAプロバイダーを起動するしくみがJavaEE5対応のアプリケーションサーバに組み込まれているため、JPAの仕様に従って、META-DATA/persistence.xmlファイルが格納されていると、アプリケーションサーバーによって読み込まれて処理されます。読み込まれたJPAの永続ユニットはローカルのJNDIコンテキストから参照できます。

しかしながら、

  • persistence.xmlの動作は環境によってかなり差異がある(パスの解決方法など)
  • 開発時は軽量なTomcatのようなサーバーで開発したい

などの理由により、アプリケーションサーバーにJPAを処理させずに、Springの軽量コンテナーに処理させるという方法も時として便利です。このような場合、アプリケーションサーバーにpersistence.xmlを認識させないための、てっとり早い方法としては、persistence.xmlをpersistece-spring.xmlなどにリネームし、これをSpringに読み込ませるという方法があります。

	
	<bean id="emf"
		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="persistenceUnitName" value="sampleDB" />
		
		<property name="persistenceXmlLocation" value="classpath*:META-INF/spring-persistence.xml" />
		<property name="dataSource" ref="dataSource" />
		<property name="jpaVendorAdapter">
			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
				<property name="database" value="MYSQL" />
				<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" />
			</bean>
		</property>
		<property name="jpaDialect">
			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />
		</property>
	</bean>

しかし、この方法ではJBoss AS5*1上で正しくJPAを動作させることができないようです。実際、以下の例外となりアプリケーションが起動しません。

java.lang.IllegalArgumentException: Can't find a persistence unit named 'null' in AbstractVFSDeploymentContext@2123658583{vfszip:/D:/development/tools/JBoss/jboss-5.1.0.GA/server/default/deploy/sample.war/}
	at org.jboss.jpa.resolvers.BasePersistenceUnitDependencyResolver.resolvePersistenceUnitSupplier(BasePersistenceUnitDependencyResolver.java:107)
	at org.jboss.web.tomcat.service.TomcatInjectionContainer.resolvePersistenceUnitSupplier(TomcatInjectionContainer.java:685)
	at org.jboss.injection.PersistenceUnitHandler.addPUDependency(PersistenceUnitHandler.java:130)

Springのアプリケーションでは部分的にJavaEEの標準アノテーションが利用できるようになっており、例えば、EJBでないPojoのDAOクラスの中で@PersisteceContextアノテーションを利用することができます。しかし、なぜか、このアノテーションJBossに認識されてしまうという問題があるようです。(本来であれば、EJBサーブレットなど特定のJavaEEコンポーネント上でしか認識してほしくないのですが。)今の場合、persistence.xmlを別名にリネームしているため永続ユニットが初期化されていないとJBossに認識されているため、@PersistenceContextアノテーションの読み込みがされた時点でチェックされて上記のエラーとなるようです。この問題について、しばらく悩んでいたのですが、以下に解決策のヒントが書かれていました。

[JBSEAM-3587] Spring example on AS 5 throwns a non-jta-data-source error while deploying - JBoss Issue Tracker

結局、対処としては、web.xmlの<web-app>タグにmetadata-complete="true"をつけてやればよいようです。

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://java.sun.com/xml/ns/javaee" 
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" 
id="WebApp_ID" version="2.5" metadata-complete="true">

	<display-name>Archetype Created Web Application</display-name>

	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>
			classpath:appCommonContext.xml
			/WEB-INF/applicationContext.xml
		</param-value>
	</context-param>

	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
...
</web-app>

この属性により、JBossxmlファイルによって設定が完結していると認識し、勝手にPojo内のアノテーションを探しに行く動作が抑制されるようです。さらに嬉しいことに、この属性により、起動時間も多少軽くなるようです。

ちなみに、以前からJBossとSpringの相性はよくなく、VFSから設定ファイルを読み込めず、Spring2.5まではSpring MVCがそのままでは起動すらしないという状態でした。SpringとJBossの連携については以下のプロジェクトも知られています。

Snowdrop - Cloud native Spring Boot applications

Spring3ではかなり相性の問題は解決されているようですが、古いバージョンを利用する場合には以上に紹介した連携モジュールの仕掛けが役に立つかもしれません。

*1JBoss AS6は今のところ未確認

2010-12-15

リモート(別プロセス)のJBossサーバー上のキューにXAトランザクション内で正しくメッセージを送受信するには(続編)

以前にJBoss Messagingでリモートのキューに対してXAトランザクション内でメッセージを送受信するにはResourceAdapterの登録が必要であるということを紹介いたしました。

リモート(別プロセス)のJBossサーバー上のキューにXAトランザクション内で正しくメッセージを送受信するには - 達人プログラマーを目指して

JBoss MessagingのクライアントAPIは直接はXAのリソースとしてトランザクションに参加してくれないため、一旦リソースアダプターを使ってJCAリソースプールとしてサーバーに登録しないといけないということです。ということで、理屈は頭でなんとなく理解できていたつもりだったのですが、今日実際に会社の環境で試したら、ほんのちょっとの設定の違いで正しくリモートのキューがJNDIルックアップできず結構な時間はまってしまいました。上記の記事で説明した通り、deploy\messaging\jms-ds.xmlに対してJMSProviderLoaderと接続ファクトリーに対するタグを追加すればよいのですが、以下の書き方ではリモートのキューのJNDIルックアップがうまくいきません。

   
  <mbean code="org.jboss.jms.jndi.JMSProviderLoader"
     name="jboss.messaging:service=JMSProviderLoader,name=RemoteJMSProvider">
    <attribute name="ProviderName">RemoteJMSProvider</attribute>
    <attribute name="ProviderAdapterClass">
      org.jboss.jms.jndi.JNDIProviderAdapter
    </attribute>
    
    <attribute name="FactoryRef">java:/XAConnectionFactory</attribute>
    
    <attribute name="QueueFactoryRef">java:/XAConnectionFactory</attribute>
    
    <attribute name="TopicFactoryRef">java:/XAConnectionFactory</attribute>
    
    <attribute name="Properties">
       java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
       java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
       java.naming.provider.url=リモートのアドレス:1099
    </attribute>
  </mbean>

  
  <tx-connection-factory>
    <jndi-name>RemoteJmsXA</jndi-name>
    <xa-transaction/>
    <rar-name>jms-ra.rar</rar-name>
    <connection-definition>org.jboss.resource.adapter.jms.JmsConnectionFactory</connection-definition>
    <config-property name="SessionDefaultType" type="java.lang.String">javax.jms.Topic</config-property>
    <config-property name="JmsProviderAdapterJNDI" type="java.lang.String">java:/RemoteJMSProvider</config-property>
    <max-pool-size>20</max-pool-size>
  </tx-connection-factory>

そして、以下が正しく動作する設定です。

   
  <mbean code="org.jboss.jms.jndi.JMSProviderLoader"
     name="jboss.messaging:service=JMSProviderLoader,name=RemoteJMSProvider">
    <attribute name="ProviderName">RemoteJMSProvider</attribute>
    <attribute name="ProviderAdapterClass">
      org.jboss.jms.jndi.JNDIProviderAdapter
    </attribute>
    
    <attribute name="FactoryRef">/XAConnectionFactory</attribute>
    
    <attribute name="QueueFactoryRef">/XAConnectionFactory</attribute>
    
    <attribute name="TopicFactoryRef">/XAConnectionFactory</attribute>
    
    <attribute name="Properties">
       java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
       java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
       java.naming.provider.url=リモートのアドレス:1099
    </attribute>
  </mbean>

  
  <tx-connection-factory>
    <jndi-name>RemoteJmsXA</jndi-name>
    <xa-transaction/>
    <rar-name>jms-ra.rar</rar-name>
    <connection-definition>org.jboss.resource.adapter.jms.JmsConnectionFactory</connection-definition>
    <config-property name="SessionDefaultType" type="java.lang.String">javax.jms.Topic</config-property>
    <config-property name="JmsProviderAdapterJNDI" type="java.lang.String">java:/RemoteJMSProvider</config-property>
    <max-pool-size>20</max-pool-size>
  </tx-connection-factory>

間違い探しのようですが違いがわかりますか。つまりFactoryRefのアドレスがjava:/XAConnectionFactoryではなくて/XAConnectionFactoryでなくてはならないということです。java:の部分が余分ということですね。確かに、もともと参考にしたサンプルでもjava:の部分は付いていなかったのですが、もともとjms-ds.xml上に定義されていたローカルのキュー用の設定ではjava:/XAConnectionFactoryと指定されていたため、どうせなら統一しておいたほうが美しいだろうということで無意識のうちにすべてjava:をつけてしまい、それでアクセスできなくなっていたのですね。

ちなみに、上記のような設定をしておいた場合

  • ローカルのJNDIツリーからjava:/RemoteJmsXAというJNDI名で接続ファクトリーをルックアップ
  • キューをリモートのJNDIツリーからリモートサーバーのキュー名(/queue/TestQueueなど)でルックアップ

という流れになります。ルックアップするJNDIツリーが接続ファクトリーとキューとで異なるので注意が必要です。Springを使う場合は以下のような設定となりますね。とにかく非常にややこしいです。(コメント欄のnekopさんのアドバイスを参照してExternalContextという機能を使うとアプリ内でリモートのJNDIツリーを意識せずに済むようです。リモートサーバーのアドレス設定が一元管理できるのでそちらの方が一般的にベターでしょう。)

	
	<jee:jndi-lookup id="connectionFactory" jndi-name="java:/RemoteJmsXA" />

	
	<bean id="remoteJmsTemplate" class="org.springframework.jms.core.JmsTemplate">
		<property name="connectionFactory" ref="connectionFactory" />
		<property name="receiveTimeout" value="10000" />
		<property name="destinationResolver" ref="destinationResolver" />
	</bean>

	<bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate">
		<property name="environment">
			<props>
				<prop key="java.naming.factory.initial">org.jnp.interfaces.NamingContextFactory</prop>
				<prop key="java.naming.factory.url.pkgs">org.jboss.naming:org.jnp.interfaces</prop>
				<prop key="java.naming.provider.url">jnp://リモートアドレス:1099</prop>
			</props>
		</property>
	</bean>

	<bean id="destinationResolver" class="org.springframework.jms.support.destination.JndiDestinationResolver" >
		<property name="jndiTemplate" ref="jndiTemplate"  />
	</bean>

なおHow to send a tx transactional jms message from a local jboss to a remote jboss (version?4.2.3.GA) | My notesでは1100番ポートのHA-JNDIを使うサンプルとなっていますが、クラスタ環境は必須ではなく普通のレプリケートされないJNDIツリーで大丈夫です。

最終的にjava - Sending JMS message to remote queue in JBoss AS via connection pool - Stack Overflowを参考にさせていただきました。

2010-12-12

EJBコンテナー、Webコンテナー内で管理されたJMS接続から同時に複数のSessionを生成できない

以下の条件を満たすとJBoss Messaging + Spring MDPの環境で以下の例外となります。

  • java:/JmsXAからXA対応(JCAリソースアダプター経由)の接続ファクトリを使用
  • concurrency属性を2以上に設定
  • cache属性をsession以上に設定
javax.jms.JMSException: Could not create a session: javax.jms.IllegalStateException: Only allowed one session per connection. See the J2EE spec, e.g. J2EE1.4 Section 6.6
	at org.jboss.resource.adapter.jms.JmsSessionFactoryImpl.allocateConnection(JmsSessionFactoryImpl.java:426)
	at org.jboss.resource.adapter.jms.JmsSessionFactoryImpl.createSession(JmsSessionFactoryImpl.java:374)
	at org.springframework.jms.support.JmsAccessor.createSession(JmsAccessor.java:196)
	at org.springframework.jms.listener.DefaultMessageListenerContainer.access$12(DefaultMessageListenerContainer.java:1)
	at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.initResourcesIfNecessary(DefaultMessageListenerContainer.java:1078)
	at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:1057)
	at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:952)
	at org.springframework.jca.work.DelegatingWork.run(DelegatingWork.java:57)
	at org.jboss.resource.work.WorkWrapper.execute(WorkWrapper.java:205)
	at org.jboss.util.threadpool.BasicTaskWrapper.run(BasicTaskWrapper.java:260)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:662)

実際にJavaEE仕様書の6.6節には以下の記述があります。

Application components in the web and EJB containers must not attempt to create more than one active (not closed) Session object per connection. An attempt to use the Connection object’s createSession method when an active Session object exists for that connection should be prohibited by the container. The container may throw a JMSException if the application component violates this restriction. Application client containers must support the creation of multiple sessions for each connection.

つまり、EJBやWebコンテナー内のコンポーネントを同一のJMS接続から同時に複数のアクティブなSessionを作成できないということですね。(外部のクライアントの場合は逆に複数の接続を作成できなくてはならないようです。)

したがって、以下のXA対応の管理されたキューに対するJMS接続を使用する場合は以下のいずれかの設定にする必要があります。

<jms:listener-container 
		concurrency="1" 
		cache="consumer"
		... >


<jms:listener-container 
		concurrency="2以上" 
		cache="none"
		... >

ただし、通常トピックの場合は同時に同じメッセージを受信しても困るのと、subscriberは常にアクティブでないと受信漏れが発生するため、前者の設定しか取りえません。

なお、この問題はSpring固有の問題ではなくて、JavaEEの仕様の問題なのでSeamでも発生するケースがあるようです。rarファイルの設定により、JavaEEの仕様に厳密に従わずに複数のJMS Sessionの生成を可能にすることも可能なようです。

404 Not Found

2010-12-02

JBoss Messagingでメッセージの永続化ストアを使わなくする方法

JBoss MessagingではデフォルトでHSQLを使ったJMSメッセージの永続化が設定されています。メッセージの永続化は、メッセージの配信を保障するために重要な機構ですが、開発や単体試験実行時に、サーバーを再起動してもキュー内のメッセージが消えないと非常に不便で、逆にトラブルの元になります。

サーバーディレクトリー\deploy\messaging

に格納されている、hsqldb-persistence-service.xmlを単純に削除し、

\docs\examples\jms\null-persistence-service.xml

を代わりにコピーするだけでは、以下の例外となってサーバー自体が起動しなくなります。

java.lang.RuntimeException: Unable to locate the transaction manager
	at org.jboss.tm.TransactionManagerLocator.locate(TransactionManagerLocator.java:134)
	at org.jboss.tm.TransactionManagerLocator.locate(TransactionManagerLocator.java:113)
	at org.jboss.messaging.core.jmx.JDBCServiceSupport.getTransactionManagerReference(JDBCServiceSupport.java:175)
	at org.jboss.jms.server.plugin.JDBCJMSUserManagerService.startService(JDBCJMSUserManagerService.java:74)
	at org.jboss.system.ServiceMBeanSupport.jbossInternalStart(ServiceMBeanSupport.java:376)
	at org.jboss.system.ServiceMBeanSupport.start(ServiceMBeanSupport.java:269)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)
	at org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatcher.java:157)
	at org.jboss.mx.server.Invocation.dispatch(Invocation.java:96)
	at org.jboss.mx.interceptor.AbstractInterceptor.invoke(AbstractInterceptor.java:138)
	at org.jboss.mx.server.Invocation.invoke(Invocation.java:90)
	at org.jboss.mx.interceptor.ModelMBeanOperationInterceptor.invoke(ModelMBeanOperationInterceptor.java:140)
	at org.jboss.mx.server.Invocation.invoke(Invocation.java:90)
	at org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.java:264)
	at org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:668)
	at org.jboss.system.microcontainer.ServiceProxy.invoke(ServiceProxy.java:206)
	at $Proxy38.start(Unknown Source)
	at org.jboss.system.microcontainer.StartStopLifecycleAction.installAction(StartStopLifecycleAction.java:42)
	at org.jboss.system.microcontainer.StartStopLifecycleAction.installAction(StartStopLifecycleAction.java:37)
	at org.jboss.dependency.plugins.action.SimpleControllerContextAction.simpleInstallAction(SimpleControllerContextAction.java:62)
	at org.jboss.dependency.plugins.action.AccessControllerContextAction.install(AccessControllerContextAction.java:71)
	at org.jboss.dependency.plugins.AbstractControllerContextActions.install(AbstractControllerContextActions.java:51)
	at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348)
	at org.jboss.system.microcontainer.ServiceControllerContext.install(ServiceControllerContext.java:286)
	at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1631)
	at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:934)
	at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1082)
	at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:984)
	at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:822)
	at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:553)
	at org.jboss.system.ServiceController.doChange(ServiceController.java:688)
	at org.jboss.system.ServiceController.start(ServiceController.java:460)
	at org.jboss.system.deployers.ServiceDeployer.start(ServiceDeployer.java:163)
	at org.jboss.system.deployers.ServiceDeployer.deploy(ServiceDeployer.java:99)
	at org.jboss.system.deployers.ServiceDeployer.deploy(ServiceDeployer.java:46)
	at org.jboss.deployers.spi.deployer.helpers.AbstractSimpleRealDeployer.internalDeploy(AbstractSimpleRealDeployer.java:62)
	at org.jboss.deployers.spi.deployer.helpers.AbstractRealDeployer.deploy(AbstractRealDeployer.java:50)
	at org.jboss.deployers.plugins.deployers.DeployerWrapper.deploy(DeployerWrapper.java:171)
	at org.jboss.deployers.plugins.deployers.DeployersImpl.doDeploy(DeployersImpl.java:1439)
	at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:1157)
	at org.jboss.deployers.plugins.deployers.DeployersImpl.doInstallParentFirst(DeployersImpl.java:1178)
	at org.jboss.deployers.plugins.deployers.DeployersImpl.install(DeployersImpl.java:1098)
	at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348)
	at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1631)
	at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:934)
	at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1082)
	at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:984)
	at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:822)
	at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:553)
	at org.jboss.deployers.plugins.deployers.DeployersImpl.process(DeployersImpl.java:781)
	at org.jboss.deployers.plugins.main.MainDeployerImpl.process(MainDeployerImpl.java:702)
	at org.jboss.system.server.profileservice.repository.MainDeployerAdapter.process(MainDeployerAdapter.java:117)
	at org.jboss.system.server.profileservice.repository.ProfileDeployAction.install(ProfileDeployAction.java:70)
	at org.jboss.system.server.profileservice.repository.AbstractProfileAction.install(AbstractProfileAction.java:53)
	at org.jboss.system.server.profileservice.repository.AbstractProfileService.install(AbstractProfileService.java:361)
	at org.jboss.dependency.plugins.AbstractControllerContext.install(AbstractControllerContext.java:348)
	at org.jboss.dependency.plugins.AbstractController.install(AbstractController.java:1631)
	at org.jboss.dependency.plugins.AbstractController.incrementState(AbstractController.java:934)
	at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:1082)
	at org.jboss.dependency.plugins.AbstractController.resolveContexts(AbstractController.java:984)
	at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:822)
	at org.jboss.dependency.plugins.AbstractController.change(AbstractController.java:553)
	at org.jboss.system.server.profileservice.repository.AbstractProfileService.activateProfile(AbstractProfileService.java:306)
	at org.jboss.system.server.profileservice.ProfileServiceBootstrap.start(ProfileServiceBootstrap.java:271)
	at org.jboss.bootstrap.AbstractServerImpl.start(AbstractServerImpl.java:461)
	at org.jboss.Main.boot(Main.java:221)
	at org.jboss.Main$1.run(Main.java:556)
	at java.lang.Thread.run(Unknown Source)

解決策は以下に載っていました。

Persistence Manager Problem - null-persistence-... |JBoss Developer

ステップ1
サーバーディレクトリー\deploy\messaging\hsqldb-persistence-service.xml

を削除する。

ステップ2
サーバーディレクトリー\deploy\messaging\messaging-jboss-beans.xml

の10行からの以下のタグをコメントアウト。

   <application-policy xmlns="urn:jboss:security-beans:1.0" name="messaging">
      <authentication>
         <login-module code="org.jboss.security.auth.spi.DatabaseServerLoginModule" flag="required">
            <module-option name="unauthenticatedIdentity">guest</module-option>
            <module-option name="dsJndiName">java:/DefaultDS</module-option>
            <module-option name="principalsQuery">SELECT PASSWD FROM JBM_USER WHERE USER_ID=?</module-option>
            <module-option name="rolesQuery">SELECT ROLE_ID, 'Roles' FROM JBM_ROLE WHERE USER_ID=?</module-option>
         </login-module>
      </authentication>
   </application-policy>
ステップ3
サーバーディレクトリー\conf\login-config.xml

に、以下を追加。

<application-policy name="messaging">
 <authentication>
   <login-module code="org.jboss.security.auth.spi.UsersRolesLoginModule" flag="required">
      <module-option name = "unauthenticatedIdentity">guest</module-option>
      <module-option name="usersProperties">props/messaging-users.properties</module-option>
      <module-option name="rolesProperties">props/messaging-roles.properties</module-option>
   </login-module>
  </authentication>
</application-policy>
ステップ4

以下の内容をnull-persistence-service.xmlとして、


<?xml version="1.0" encoding="UTF-8"?>



<server>

   

   <mbean code="org.jboss.messaging.core.jmx.NullPersistenceManagerService"
      name="jboss.messaging:service=PersistenceManager"
      xmbean-dd="xmdesc/NullPersistenceManager-xmbean.xml"/>
     
   

   <mbean code="org.jboss.messaging.core.jmx.MessagingPostOfficeService"
      name="jboss.messaging:service=PostOffice"
      xmbean-dd="xmdesc/MessagingPostOffice-xmbean.xml">

      <depends optional-attribute-name="ServerPeer">jboss.messaging:service=ServerPeer</depends>
      <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends>
      
      

      <attribute name="PostOfficeName">JMS post office</attribute>
     
      

      <attribute name="Clustered">false</attribute>
 
   </mbean>

   

   <mbean code="org.jboss.jms.server.plugin.JDBCJMSUserManagerService"
      name="jboss.messaging:service=JMSUserManager"
      xmbean-dd="xmdesc/JMSUserManager-xmbean.xml">
        <depends optional-attribute-name="TransactionManager">jboss:service=TransactionManager</depends> 
   </mbean>

</server>
サーバーディレクトリー\deploy\messaging

に格納。docsフォルダーに格納されているものと違うため注意が必要です。(クラスター設定がないことと、TransactionManagerに対する依存が追加されている。)

2010-11-30

環境によってJBoss AS5.1が起動しない場合の対処方法

java.lang.IllegalArgumentException: Wrong arguments. new for target java.lang.reflect.Constructor expected=[java.net.URI] actual=[java.io.File]

突然JBossサーバーが上記のエラーを出して起動しなくなってしまいました。検索したところ、以下に解決策が示されていました。

[JBAS-6981] AttachmentStore MC bean (org.jboss.system.server.profileservice.repository.AbstractAttachmentStore) configuration does not specify the parameter type for constructor - JBoss Issue Tracker

修正手順を以下にメモします。

サーバーディレクトリー\conf\bootstrap

配下にあるprofile.xmlの146行目を以下のように修正します。



	<bean name="AttachmentStore" class="org.jboss.system.server.profileservice.repository.AbstractAttachmentStore">
		<constructor><parameter class="java.io.File"><inject bean="BootstrapProfileFactory" property="attachmentStoreRoot" /></parameter>
		<property name="mainDeployer"><inject bean="MainDeployer" /></property>
		<property name="serializer"><inject bean="AttachmentsSerializer" /></property>
		<property name="persistenceFactory"><inject bean="PersistenceFactory" /></property>
	</bean>

現状の実装だとコンストラクターが複数オーバーロードされており、環境によってランダムに選択されてしまうため、運が悪いとこの例外が発生して、JBossが起動しなくなってしまうようです。JDKのバージョンやインストールパスなどの環境面に依存するようですが、詳しい再現条件は不明です。