控制台打印:
javax.jms.JMSException:コンテンツから体を構築するために失敗しました。直列化可能クラスブローカーに利用できません。
理由:にjava.lang.ClassNotFoundException:禁断のクラス com.javaliao.portal.model.TbLogVisit!
このクラスは、のObjectMessageペイロードとしてシリアル化する信頼されていません。見てみてください
ます。http:// activemq.apache.org/objectmessage.htmlを信頼されたクラスを設定する方法に関する詳細については。 org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSupport.java:36で) org.apache.activemq.command.ActiveMQObjectMessage.getObjectで(ActiveMQObjectMessage.java: 213 ) com.javaliao.portal.listener.LogVisitListener.consumePaymentResultで(LogVisitListener.java: 50 ) sun.reflect.NativeMethodAccessorImpl.invoke0で(ネイティブメソッド) でsun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java: 62 ) sun.reflect.DelegatingMethodAccessorImpl.invokeで(DelegatingMethodAccessorImpl.java: 43 ) java.lang.reflect.Method.invokeで(Method.java: 497 ) org.springframework.messaging.handler.invocation.InvocableHandlerMethod.doInvokeで(InvocableHandlerMethod.java: 171 )
この問題は発生します。
が、通常それは生産者と消費者との間に結合されたクラスパスを導入しているため、のObjectMessageの使用を奨励するが、ActiveMQのJMS仕様の一部としてそれらをサポートしていません。
セキュリティ
のObjectMessage依存オブジェクトのマーシャル/アンマーシャリングオブジェクトは、Java直列化をサポート。悪意のあるペイロードがホストシステムを攻撃するために使用することができますので、このプロセスは、一般的に、安全ではないと考えられています。これは、明示的にリストがパッケージObjectMessages交換ホワイトリストを使用することができますようにユーザーに強制するのActiveMQ、なぜバージョンから5.12.2と5.13.0始まりです。
あなたがオブジェクトメッセージを交換する必要がある場合は、アプリケーション・パッケージが使用されて追加する必要があります。(エージェントとActiveMQのクライアントライブラリによって解釈)システムプロパティをorg.apache.activemq.serializable_packages使用することにより、これを行うことができます。あなたはactivemq_optsシステム変数$ {activemq_home} / binに/ ENVスクリプトにこのプロパティを追加することができます。
例えば
-dorg.apache.activemq.serializable_packages = java.langで、javax.security、java.utilで、 org.apache.activemq、org.fusesource.hawtbuf、com.thoughtworks.xstream.mapper、com.mycompany.myappと
COMをでしょう。 mycompany.myappパッケージは、彼らは正規代理店の仕事のために必要であるようにここに記載されている他のパッケージは、デフォルトで有効になっていることを信頼できるパッケージノートのリストに追加されます。あなたはこのメカニズムを簡素化したい場合は、次のようなすべてのパッケージを、信頼する*ワイルドカードを使用することができます
-dorg.apache.activemq.serializable_パッケージ= *
お客様
クライアント側では、あなたは、このようにアプリケーション環境を損なう、objectMessage.getObject()呼び出しのデシリアライゼーションの悪意のあるコード、同じメカニズムで使用する必要があります。あなたが代理機構に同じ設定を使用して、信頼できるクラスを設定するには、システムプロパティを使用することができ、しかし、これは、クライアント・アプリケーションのため通常は不便であるため、5.12.2及び5.13.1に、我々はactivemqconnectionfactoryの使用をご紹介します追加の構成メカニズム。二つの追加のメソッドを定義します:
setTrustedPackages()メソッドは、次のようなシリアライズさの信頼できるパケットのリスト中止するように設定することができます
activemqconnectionfactory =新新activemqconnectionfactory(「:// localhostを:TCP 61616を」);
factory.setTrustedPackages(新しいArrayListを( Arrays.asList( "org.apache.activemq.test、org.apache.camel.test.split("、「)));
setTrustAllPackages()はセキュリティチェックを可能にし、それはテストのために有用であるすべてのクラスの信頼を閉じ..
activemqconnectionfactory = activemqconnectionfactory新新( "TCP:// localhostを:61616");
factory.setTrustAllPackages(真);
次のような、ラクダのコンテキストで同じプロパティを設定することができます`` `
org.apache.activemq.test org.apache.camel。テストテスト
または
`システムプロパティが設定されている場合は、` `、これは構成属性を上書きします。
私のコード:
メッセージコード:
@Autowired ActiveMQUtil activeMQUtil; @オーバーライド 公共のボイドinsertLogVisit(TbLogVisit tbLogVisit){ //非同期実行中にデータベースに格納された情報を使用してメッセージキューを送信 {試します //接続メッセージングサーバー 接続の接続= activeMQUtil.getConnection()。 connection.start(); //最初の値は、あなたが真の選択した場合、トランザクションは、第2の値が0を選択することと等価であるかどうかを示します セッションsession = connection.createSession(真、Session.SESSION_TRANSACTED)。 //メッセージを送ります キューtestqueue = session.createQueue( "LOG_VISIT_QUEUE")。 MessageProducerプロデューサ= session.createProducer(testqueue)。 ObjectMessageのObjectMessage = session.createObjectMessage()。 / * AMQ_SCHEDULED_DELAY長い遅延納期 REPEAT AMQ_SCHEDULED_PERIOD長い間隔 AMQ_SCHEDULED_REPEAT int型の繰り返し配信数 AMQ_SCHEDULED_CRON文字列のCron表現* / // 30代のための時間を設定します objectMessage.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY、* 30 1000)。 objectMessage.setObject(tbLogVisit)。 //設定持続的送信 producer.setDeliveryMode(はDeliveryMode.PERSISTENT)。 producer.send(のObjectMessage)。 session.commit(); //トランザクションメッセージの後に、あなたは発効を提出しなければなりません connection.close(); }キャッチ(たJMSException電子){ e.printStackTrace(); } }
接続ツール:
com.javaliao.portal.utilパッケージ; 輸入org.apache.activemq.ActiveMQConnectionFactory; 輸入org.apache.activemq.pool.PooledConnectionFactory; 輸入javax.jms.Connection。 輸入javax.jms.JMSException。 輸入はjava.util.ArrayList; 輸入java.util.Arrays。 パブリッククラスActiveMQUtil { PooledConnectionFactory pooledConnectionFactory = NULL; 公共ボイドのinit(文字列brokerUrl){ ActiveMQConnectionFactory activeMQConnectionFactory =新しいActiveMQConnectionFactory(brokerUrl)。 //設定するホワイトリストパッケージ activeMQConnectionFactory.setTrustedPackages( 新しいArrayListを(は、Arrays.asList( "org.apache.activemq.test、org.apache.camel.test" .split( "")))); (真)activeMQConnectionFactory.setTrustAllPackages。 pooledConnectionFactory =新しいPooledConnectionFactory(activeMQConnectionFactory)。 pooledConnectionFactory.setExpiryTimeout(2000); pooledConnectionFactory.setMaximumActiveSessionPerConnection(10)。 pooledConnectionFactory.setMaxConnections(30)。 pooledConnectionFactory.setReconnectOnException(真の); } パブリック接続のgetConnection(){ 接続の接続= NULL; {試します 接続= pooledConnectionFactory.createConnection()。 }キャッチ(たJMSException電子){ e.printStackTrace(); } 接続を返します。 } }
Configurationクラス:
com.javaliao.portal.configパッケージ。 輸入com.javaliao.portal.util.ActiveMQUtil。 輸入org.apache.activemq.ActiveMQConnectionFactory; 輸入org.springframework.beans.factory.annotation.Value。 輸入org.springframework.context.annotation.Bean。 輸入org.springframework.context.annotation.Configuration。 輸入org.springframework.jms.config.DefaultJmsListenerContainerFactory; 輸入javax.jms.JMSException。 輸入javax.jms.Sessionの。 @設定 パブリッククラスActiveMQConfig { @value( "$ {spring.activemq.broker-URL:無効}") 文字列brokerURL; @value( "$ {activemq.listener.enable:無効}") 文字列listenerEnable; @豆 公共ActiveMQUtil getActiveMQUtil(){たJMSExceptionをスロー {()brokerURL.equals( "無効")の場合 ヌルを返します。 } ActiveMQUtil activeMQUtil =新しいActiveMQUtil(); activeMQUtil.init(brokerURL)。 activeMQUtilを返します。 } @豆 公共ActiveMQConnectionFactory activeMQConnectionFactory(){ {/ * IF() "(URL == nullの|| url.equals( ""))&&!brokerURL.equals(" 無効) URL = brokerURL。 } * / ActiveMQConnectionFactory activeMQConnectionFactory = 新しいActiveMQConnectionFactory(brokerURL)。 activeMQConnectionFactoryを返します。 } //メッセージ・リスナー・コネクション・ファクトリの定義は、本明細書で定義される、接続ファクトリリスナーを指すようにポイントであります @Bean(名前= "jmsQueueListener") 公共DefaultJmsListenerContainerFactory jmsQueueListenerContainerFactory(ActiveMQConnectionFactory activeMQConnectionFactory){ DefaultJmsListenerContainerFactory工場=新しいDefaultJmsListenerContainerFactory(); (もし!listenerEnable.equals( "真")){ ヌルを返します。 } factory.setConnectionFactory(activeMQConnectionFactory)。 //同時の設定数 factory.setConcurrency( "5"); //再接続間隔 factory.setRecoveryInterval(5000L)。 factory.setSessionTransacted(偽); factory.setSessionAcknowledgeMode(Session.CLIENT_ACKNOWLEDGE)。 工場を返します。 } }
エンティティクラス:
インポートしたjava.io.Serializable; 輸入java.util.Date; パブリッククラスTbLogVisitは{Serializableを実装します プライベート静的最終長いserialVersionUIDの= 2659644940173539668L。 プライベートロングID。 プライベート文字列visitIpAddress。 プライベート文字列visitHostName。 プライベート文字列visitChannel。 プライベート文字列visitDescription。 プライベート文字列visitApi。 プライベート文字列visitParams。 プライベート文字列visitUrl。 プライベート文字列visitTimeConsuming。 プライベート文字列visitResult。 プライベートロングvisitNum。 プライベート文字列visitThrowingErro。 プライベート日付visitStartTime。 プライベート日付visitEndTime。 プライベート日付CREATETIME。 プライベート日付updateTime。
メッセージが表示されます。
com.javaliao.portal.listenerパッケージ。 輸入com.javaliao.portal.log4j.BaseLogger。 輸入com.javaliao.portal.model.TbLogVisit。 輸入com.javaliao.portal.service.ActionService。 輸入org.springframework.beans.factory.annotation.Autowired; 輸入org.springframework.jms.annotation.JmsListener。 輸入org.springframework.stereotype.Component。 輸入javax.jms.JMSException。 インポートのjavax.jms.Message; 輸入javax.jms.ObjectMessage。 @成分 パブリッククラスLogVisitListener { @Autowired ActionService actionService; / ** *ギャップを反映するために、我々はJSONを使用して、おそらく35メガバイトの変換を中心に、特別なクラスの多くを作りました *使用してJSONの伝送単位はミリ秒は以下のとおりです。 *合計時間:17366 *伝送時間:220 * JSON日にオブジェクトの送信者:6271 *合計時間を送信:10000 *メッセージの受信者は、TextMessageの時間に変換されます:0 * JSONオブジェクトの時間に変換する受信者:7146を。 * **************************************** *使用のObjectMessage伝送状況: *合計時間:6742 *伝送時間:173 *合計時間を送信:4836 *メッセージの受信者は、ObjectMessageの時間に変換されます:1733 * ****************************************** *まとめ *彼はストレステストをしませんでしたが、しかし唯一の時間のために、テスト環境は、ちょうど私のラップトップですが、私は私が結論を出すことができると思いますけれども。 *サーバとの間の非同期通信では、JSONより物体。 主配列内*利点とカートリッジのJSONオブジェクトの変換効率よりもはるかに効率的との間にJavaオブジェクトを変換し、 *さらなる理由は、オブジェクトのサイズも送信後シリアライズ有利JSONよりも小さくなっています。 * / @JmsListener(containerFactory = "jmsQueueListener"、宛先= "LOG_VISIT_QUEUE") 公共のボイドconsumePaymentResult(メッセージのMapMessage){ {試します ObjectMessage tbLogVisitObject =(のObjectMessage)際、MapMessage。 TbLogVisit物体=(TbLogVisit)tbLogVisitObject.getObject(); int型のカウント= actionService.insertLog(オブジェクト); 場合(カウント<1){ BaseLogger.info( "ログの更新に失敗しました"); } }キャッチ(たJMSException電子){ e.printStackTrace(); } } }
application.preperties:
#activemqメッセージキュー spring.activemq.broker-URL = TCP://192.168.134.100:61616 真= activemq.listener.enable
あそこ構成:
私のシステムは、Linuxに設定されています