\n \u003Cproperty name=\"start\" value=\"true\" />\n\u003C/bean>\n\u003C!-- a simple test queue - the queue name is specified by the bean id -->\n\u003Cbean id=\"testQueue\" class=\"org.apache.activemq.command.ActiveMQQueue\" />\n\u003C!-- JMS connection factory (wrapped into a pooling connection factory) -->\n\u003Cbean id=\"jmsFactory\" class=\"org.apache.activemq.pool.PooledConnectionFactory\" destroy-method=\"stop\">\n \u003Cproperty name=\"connectionFactory\">\n \u003Cbean class=\"org.apache.activemq.ActiveMQConnectionFactory\">\n \u003Cproperty name=\"brokerURL\" value=\"tcp://localhost:61616\" />\n \u003C/bean>\n \u003C/property>\n\u003C/bean>\n\u003C!-- simple message listener just logging received message to stdout -->\n\u003Cbean id=\"simpleListener\" class=\"com.synyx.prototype.jms.SimpleMessageListener\" />\n\u003C!-- listener container delegating to listener instances and wiring them to their destinations -->\n\u003Cjms:listener-container concurrency=\"10\" connection-factory=\"jmsFactory\">\n \u003Cjms:listener id=\"queueListener\" destination=\"testQueue\" ref=\"simpleListener\" />\n\u003C/jms:listener-container>\n\n","xml",[96,159,160,165,170,175,181,187,193,199,205,211,217,223,229,235,241,247,252,258,264,270,276,282],{"__ignoreMap":11},[99,161,162],{"class":101,"line":102},[99,163,164],{"emptyLinePlaceholder":23},"\n",[99,166,167],{"class":101,"line":12},[99,168,169],{},"\u003C!-- create message broker - instead of using a somewhere centralized activemq server -->\n",[99,171,172],{"class":101,"line":131},[99,173,174],{},"\u003Cbean id=\"broker\" class=\"org.apache.activemq.xbean.BrokerFactoryBean\">\n",[99,176,178],{"class":101,"line":177},4,[99,179,180],{}," \u003Cproperty name=\"config\" value=\"classpath:META-INF/activemq.xml\" />\n",[99,182,184],{"class":101,"line":183},5,[99,185,186],{}," \u003Cproperty name=\"start\" value=\"true\" />\n",[99,188,190],{"class":101,"line":189},6,[99,191,192],{},"\u003C/bean>\n",[99,194,196],{"class":101,"line":195},7,[99,197,198],{},"\u003C!-- a simple test queue - the queue name is specified by the bean id -->\n",[99,200,202],{"class":101,"line":201},8,[99,203,204],{},"\u003Cbean id=\"testQueue\" class=\"org.apache.activemq.command.ActiveMQQueue\" />\n",[99,206,208],{"class":101,"line":207},9,[99,209,210],{},"\u003C!-- JMS connection factory (wrapped into a pooling connection factory) -->\n",[99,212,214],{"class":101,"line":213},10,[99,215,216],{},"\u003Cbean id=\"jmsFactory\" class=\"org.apache.activemq.pool.PooledConnectionFactory\" destroy-method=\"stop\">\n",[99,218,220],{"class":101,"line":219},11,[99,221,222],{}," \u003Cproperty name=\"connectionFactory\">\n",[99,224,226],{"class":101,"line":225},12,[99,227,228],{}," \u003Cbean class=\"org.apache.activemq.ActiveMQConnectionFactory\">\n",[99,230,232],{"class":101,"line":231},13,[99,233,234],{}," \u003Cproperty name=\"brokerURL\" value=\"tcp://localhost:61616\" />\n",[99,236,238],{"class":101,"line":237},14,[99,239,240],{}," \u003C/bean>\n",[99,242,244],{"class":101,"line":243},15,[99,245,246],{}," \u003C/property>\n",[99,248,250],{"class":101,"line":249},16,[99,251,192],{},[99,253,255],{"class":101,"line":254},17,[99,256,257],{},"\u003C!-- simple message listener just logging received message to stdout -->\n",[99,259,261],{"class":101,"line":260},18,[99,262,263],{},"\u003Cbean id=\"simpleListener\" class=\"com.synyx.prototype.jms.SimpleMessageListener\" />\n",[99,265,267],{"class":101,"line":266},19,[99,268,269],{},"\u003C!-- listener container delegating to listener instances and wiring them to their destinations -->\n",[99,271,273],{"class":101,"line":272},20,[99,274,275],{},"\u003Cjms:listener-container concurrency=\"10\" connection-factory=\"jmsFactory\">\n",[99,277,279],{"class":101,"line":278},21,[99,280,281],{}," \u003Cjms:listener id=\"queueListener\" destination=\"testQueue\" ref=\"simpleListener\" />\n",[99,283,285],{"class":101,"line":284},22,[99,286,287],{},"\u003C/jms:listener-container>\n",[41,289,290],{},"On the side of the message producer a QueueConnectionFactory implementation provides the connectivity to the ActiveMQ\nbroker. For our prototype it lacks any authentication mechanisms.",[90,292,296],{"className":293,"code":294,"language":295,"meta":11,"style":11},"language-java shiki shiki-themes github-light github-dark","\npublic class ActiveMQQueueConnectionFactory implements QueueConnectionFactory {\n private ConnectionFactory connectionFactory = null;\n public ActiveMQQueueConnectionFactory(String brokerUrl) {\n this.connectionFactory = new ActiveMQConnectionFactory(brokerUrl);\n }\n public QueueConnection createQueueConnection() throws JMSException {\n return (QueueConnection) createConnection();\n }\n public QueueConnection createQueueConnection(String username, String password) throws JMSException {\n return createQueueConnection();\n }\n public Connection createConnection() throws JMSException {\n return this.connectionFactory.createConnection();\n }\n public Connection createConnection(String username, String password) throws JMSException {\n return createConnection();\n }\n}\n\n","java",[96,297,298,302,307,312,317,322,327,332,337,341,346,351,355,360,365,369,374,379,383],{"__ignoreMap":11},[99,299,300],{"class":101,"line":102},[99,301,164],{"emptyLinePlaceholder":23},[99,303,304],{"class":101,"line":12},[99,305,306],{},"public class ActiveMQQueueConnectionFactory implements QueueConnectionFactory {\n",[99,308,309],{"class":101,"line":131},[99,310,311],{}," private ConnectionFactory connectionFactory = null;\n",[99,313,314],{"class":101,"line":177},[99,315,316],{}," public ActiveMQQueueConnectionFactory(String brokerUrl) {\n",[99,318,319],{"class":101,"line":183},[99,320,321],{}," this.connectionFactory = new ActiveMQConnectionFactory(brokerUrl);\n",[99,323,324],{"class":101,"line":189},[99,325,326],{}," }\n",[99,328,329],{"class":101,"line":195},[99,330,331],{}," public QueueConnection createQueueConnection() throws JMSException {\n",[99,333,334],{"class":101,"line":201},[99,335,336],{}," return (QueueConnection) createConnection();\n",[99,338,339],{"class":101,"line":207},[99,340,326],{},[99,342,343],{"class":101,"line":213},[99,344,345],{}," public QueueConnection createQueueConnection(String username, String password) throws JMSException {\n",[99,347,348],{"class":101,"line":219},[99,349,350],{}," return createQueueConnection();\n",[99,352,353],{"class":101,"line":225},[99,354,326],{},[99,356,357],{"class":101,"line":231},[99,358,359],{}," public Connection createConnection() throws JMSException {\n",[99,361,362],{"class":101,"line":237},[99,363,364],{}," return this.connectionFactory.createConnection();\n",[99,366,367],{"class":101,"line":243},[99,368,326],{},[99,370,371],{"class":101,"line":249},[99,372,373],{}," public Connection createConnection(String username, String password) throws JMSException {\n",[99,375,376],{"class":101,"line":254},[99,377,378],{}," return createConnection();\n",[99,380,381],{"class":101,"line":260},[99,382,326],{},[99,384,385],{"class":101,"line":266},[99,386,387],{},"}\n",[41,389,390],{},"The class QueueMessageSender implements a simple text message producer. Note that the JMSException isn’t caught but\npropageted to the caller. Exceptions are finally handled by the global Oracle VM Exception Handler. That way, in case of\nan exception, the exceptions message ends up in the ORA-XXXX error designation and the full stack trace is stated in\nthe user’s session log.",[90,392,394],{"className":293,"code":393,"language":295,"meta":11,"style":11},"\npublic class QueueMessageSender {\n private QueueConnectionFactory connectionFactory = null;\n public QueueMessageSender(QueueConnectionFactory connectionFactory) {\n this.connectionFactory = connectionFactory;\n }\n public void sendMessage(String destination, String message) throws JMSException {\n QueueConnection connection = null;\n try {\n connection = this.connectionFactory.createQueueConnection();\n QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);\n Queue queue = session.createQueue(destination);\n QueueSender sender = session.createSender(queue);\n TextMessage textMessage = session.createTextMessage(message);\n sender.send(textMessage);\n } finally {\n if (null != connection) {\n connection.close();\n }\n }\n }\n}\n\n",[96,395,396,400,405,410,415,420,424,429,434,439,444,449,454,459,464,469,474,479,484,489,494,498],{"__ignoreMap":11},[99,397,398],{"class":101,"line":102},[99,399,164],{"emptyLinePlaceholder":23},[99,401,402],{"class":101,"line":12},[99,403,404],{},"public class QueueMessageSender {\n",[99,406,407],{"class":101,"line":131},[99,408,409],{}," private QueueConnectionFactory connectionFactory = null;\n",[99,411,412],{"class":101,"line":177},[99,413,414],{}," public QueueMessageSender(QueueConnectionFactory connectionFactory) {\n",[99,416,417],{"class":101,"line":183},[99,418,419],{}," this.connectionFactory = connectionFactory;\n",[99,421,422],{"class":101,"line":189},[99,423,326],{},[99,425,426],{"class":101,"line":195},[99,427,428],{}," public void sendMessage(String destination, String message) throws JMSException {\n",[99,430,431],{"class":101,"line":201},[99,432,433],{}," QueueConnection connection = null;\n",[99,435,436],{"class":101,"line":207},[99,437,438],{}," try {\n",[99,440,441],{"class":101,"line":213},[99,442,443],{}," connection = this.connectionFactory.createQueueConnection();\n",[99,445,446],{"class":101,"line":219},[99,447,448],{}," QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);\n",[99,450,451],{"class":101,"line":225},[99,452,453],{}," Queue queue = session.createQueue(destination);\n",[99,455,456],{"class":101,"line":231},[99,457,458],{}," QueueSender sender = session.createSender(queue);\n",[99,460,461],{"class":101,"line":237},[99,462,463],{}," TextMessage textMessage = session.createTextMessage(message);\n",[99,465,466],{"class":101,"line":243},[99,467,468],{}," sender.send(textMessage);\n",[99,470,471],{"class":101,"line":249},[99,472,473],{}," } finally {\n",[99,475,476],{"class":101,"line":254},[99,477,478],{}," if (null != connection) {\n",[99,480,481],{"class":101,"line":260},[99,482,483],{}," connection.close();\n",[99,485,486],{"class":101,"line":266},[99,487,488],{}," }\n",[99,490,491],{"class":101,"line":272},[99,492,493],{}," }\n",[99,495,496],{"class":101,"line":278},[99,497,326],{},[99,499,500],{"class":101,"line":284},[99,501,387],{},[41,503,504],{},"The following class provides the entry point to be called from PL/SQL (i.e. sending a message triggering the service\ncall replacing the legacy trigger code). For demonstration purposes it is kept simple like the rest of the code\nexamples. Note that the method acting as entry point must be static for beeing callable from PL/SQL.",[90,506,508],{"className":293,"code":507,"language":295,"meta":11,"style":11},"\npublic class JMSFromOracleTest {\n private static final String BROKER_URL = \"tcp://192.168.x.x:61616\";\n private static final String QUEUE_NAME = \"testQueue\";\n public static void sendMessage(String message) throws JMSException {\n QueueConnectionFactory connectionFactory = new ActiveMQQueueConnectionFactory(BROKER_URL);\n QueueMessageSender sender = new QueueMessageSender(connectionFactory);\n sender.sendMessage(QUEUE_NAME, message);\n }\n}\n\n",[96,509,510,514,519,524,529,534,539,544,549,553],{"__ignoreMap":11},[99,511,512],{"class":101,"line":102},[99,513,164],{"emptyLinePlaceholder":23},[99,515,516],{"class":101,"line":12},[99,517,518],{},"public class JMSFromOracleTest {\n",[99,520,521],{"class":101,"line":131},[99,522,523],{}," private static final String BROKER_URL = \"tcp://192.168.x.x:61616\";\n",[99,525,526],{"class":101,"line":177},[99,527,528],{}," private static final String QUEUE_NAME = \"testQueue\";\n",[99,530,531],{"class":101,"line":183},[99,532,533],{}," public static void sendMessage(String message) throws JMSException {\n",[99,535,536],{"class":101,"line":189},[99,537,538],{}," QueueConnectionFactory connectionFactory = new ActiveMQQueueConnectionFactory(BROKER_URL);\n",[99,540,541],{"class":101,"line":195},[99,542,543],{}," QueueMessageSender sender = new QueueMessageSender(connectionFactory);\n",[99,545,546],{"class":101,"line":201},[99,547,548],{}," sender.sendMessage(QUEUE_NAME, message);\n",[99,550,551],{"class":101,"line":207},[99,552,326],{},[99,554,555],{"class":101,"line":213},[99,556,387],{},[48,558,560],{"id":559},"packaging-and-deployment-to-the-oracle-db","Packaging and Deployment to the Oracle DB",[41,562,563],{},"To simplify the deployment we created a small Maven project covering the producer code and used the Maven Assembly\nplugin for packaging the producer classes and all dependencies into a single JAR file. Again, to keep things simple we\nadded the activemq-all distribution as the only dependency.",[41,565,566,568,569,573],{},[138,567,140],{}," All classes (the producer classes and ",[570,571,572],"em",{},"all"," dependencies) need to be compiled using/for JDK 1.5 (class\nversion \u003C= 49.0).",[41,575,576],{},"Oracle keeps all Java class files and resources in the database. As the name implies, the command line tool “loadjava”\nis used to load Java resources into the db. This command must be issued on the Oracle DB server itself. For that, the\nenvironment variable ORACLE_HOME must be correctly set. In reverse, the tool “dropjava” provides an easy way to unload\nJava resources from the DB.",[41,578,579],{},"Issuing the following command loads all resources contained in our JAR file into the Oracle DB.",[90,581,585],{"className":582,"code":583,"language":584,"meta":11,"style":11},"language-bash shiki shiki-themes github-light github-dark","\nloadjava -v -r -u test/12345 -resolver \"((* TEST) (* PUBLIC) (* -))\" JMSSender-1.0-SNAPSHOT-jar-with-dependencies.jar\n\n","bash",[96,586,587,591],{"__ignoreMap":11},[99,588,589],{"class":101,"line":102},[99,590,164],{"emptyLinePlaceholder":23},[99,592,593,597,601,604,607,611,614,617],{"class":101,"line":12},[99,594,596],{"class":595},"sScJk","loadjava",[99,598,600],{"class":599},"sj4cs"," -v",[99,602,603],{"class":599}," -r",[99,605,606],{"class":599}," -u",[99,608,610],{"class":609},"sZZnC"," test/12345",[99,612,613],{"class":599}," -resolver",[99,615,616],{"class":609}," \"((* TEST) (* PUBLIC) (* -))\"",[99,618,619],{"class":609}," JMSSender-1.0-SNAPSHOT-jar-with-dependencies.jar\n",[41,621,622,623,626,627,630,631,633,634,637,638,641,642,645,646,649],{},"The switch ",[96,624,625],{},"-r"," enables the resolving of all classes references by the loaded classes. If any reference made by a class\ncould not be resolved, that class is marked ",[96,628,629],{},"INVALID",". Classes referencing invalid classes are also marked ",[96,632,629],{},".\nNote that we declared our own resolver using the ",[96,635,636],{},"-resolver"," parameter. Using the parameter as stated above all classes\nin any package declared in the SCHEMA ",[96,639,640],{},"TEST"," and ",[96,643,644],{},"PUBLIC"," are allowed to reference unresolved dependencies. That way\nfeatures and connectors of ActiveMQ not used (and therefore lack the required dependencies) do not invalidate the core\nclasses. The parameter ",[96,647,648],{},"-u"," is followed by the user credentials (username/password) of the user to whose default schema\nthe resources are deployed.",[41,651,652,653,656,657,62],{},"After all resources contained in the JAR file are deployed (this may take a while – but keeps you entertained because of\nthe ",[96,654,655],{},"-v"," parameter), we need to create a stored procedure usable from PL/SQL that directs the call to the entry point\nmethod of our Java implementation. For general information on calling Java Methods from PL/SQL (i.e. referencing\nparameters and return values) see ",[56,658,61],{"href":58,"rel":659},[60],[90,661,663],{"className":92,"code":662,"language":94,"meta":11,"style":11},"\nCREATE OR REPLACE PROCEDURE sendJmsMessage(message IN VARCHAR2)\nAS LANGUAGE JAVA NAME 'com.synyx.prototype.jms.JMSFromOracleTest.sendMessage(java.lang.String)';\n\n",[96,664,665,669,674],{"__ignoreMap":11},[99,666,667],{"class":101,"line":102},[99,668,164],{"emptyLinePlaceholder":23},[99,670,671],{"class":101,"line":12},[99,672,673],{},"CREATE OR REPLACE PROCEDURE sendJmsMessage(message IN VARCHAR2)\n",[99,675,676],{"class":101,"line":131},[99,677,678],{},"AS LANGUAGE JAVA NAME 'com.synyx.prototype.jms.JMSFromOracleTest.sendMessage(java.lang.String)';\n",[41,680,681],{},"Finally, we are done. Calling the procedure from PL/SQL will invoke our Java method and a text message containing the\ngiven text will be posted.",[90,683,685],{"className":92,"code":684,"language":94,"meta":11,"style":11},"\ncall sendjmsmessage('hello from oracle');\n\n",[96,686,687,691],{"__ignoreMap":11},[99,688,689],{"class":101,"line":102},[99,690,164],{"emptyLinePlaceholder":23},[99,692,693],{"class":101,"line":12},[99,694,695],{},"call sendjmsmessage('hello from oracle');\n",[697,698,699],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}",{"title":11,"searchDepth":12,"depth":12,"links":701},[702,703,704,705],{"id":50,"depth":12,"text":51},{"id":81,"depth":12,"text":82},{"id":148,"depth":12,"text":149},{"id":559,"depth":12,"text":560},[707],"developer-blog","2011-10-18T17:37:19","After taking over a legacy application of which a huge part of the business logic is formed by triggers and procedures\\ninside an Oracle DB, we faced the task of a step-by-step migration of that logic to Java code. Due to the complete\\nlack of a defined and sophisticated service layer and having other systems connected using several autonomous interfaces\\nwhich directly access the underlying database this migration is quite complicated.","https://synyx.de/blog/sending-jms-from-oracledb-to-external-activemq-broker/",{},"/blog/sending-jms-from-oracledb-to-external-activemq-broker",{"title":32,"description":43},"blog/sending-jms-from-oracledb-to-external-activemq-broker",[],"After taking over a legacy application of which a huge part of the business logic is formed by triggers and procedures inside an Oracle DB, we faced the task of…","8b5tf03Ms7jGKzpnvc9ei6GFG6iPwFbrgDPlVaOGXeQ",["Reactive",719],{"$scookieConsent":720,"$ssite-config":722},{"functional":721,"analytics":721},false,{"_priority":723,"env":727,"name":728,"url":729},{"name":724,"env":725,"url":726},-10,-15,0,"production","nuxt-app","https://synyx.de",["Set"],["ShallowReactive",732],{"author-menz":-1,"roughlyFilteredArticles":-1},"/blog/author/menz"]