Upload
others
View
15
Download
0
Embed Size (px)
Citation preview
LotteryWebLogic JMS, Jersey, JMX, JNDI
Óbudai Egyetem, Java Enterprise EditionMűszaki Informatika szakLabor 8
Bedők Dávid2016.01.25.v0.3
Feladat
● A Lottery alkalmazás portolása WebLogic alkalmazás szerverre.
● Remote JMS client készítése● Local JMS client készítése● JMX management lehetőségek
Nehézségek: bár az implementált osztályok csekély mértékben módosulnak, a környezeti beállítások eltérnek, és “természetesen” teljesen már library-k (implementációk) vannak használva runtime WebLogicnál (JBoss-szal összehasonlítva).
2
Architektúra (változatlan)
3
RedHat JBoss vs. Oracle WebLogic
4
JBoss 6.4 WebLogic 12.2.1
JEE version JEE6 JEE6
Logging JBoss Logging, Log4J, .. JDK Logging, ..
REST WS RESTEasy 2.3.10.Final Jersey 1.18
JPA Provider Hibernate 4.2.18.Final EclipseLink 2.5.2
JMS Provider HornetQ 2.3.25.Final WebLogic JMS
JAXB JAXB 2.2.5-redhat-9 JAXB 2.2.10 Oracle
JMS Provider beállítása IJMS Server and JMS Module
WebLogic Administration Console● Services | Messaging | JMS Servers
○ New■ name: demoJMSserver■ persistence store: none■ target: myserver
● Services | Messaging | JMS Modules○ New
■ name: demoJMSmodule■ location in domain: blank■ target: myserver■ Would you like to add resources to this JMS
system module? yes5
JMS Provider beállítása IIJMS Submodule és JMS Destination (queue)
● Services | Messaging | JMS Modules○ demoJMSmodule | Subdeployments | New
■ name: demoJMSsubmodule■ target/server: demoJMSserver■ target: myserver■ Would you like to add resources to this JMS
system module? yes● Services | Messaging | JMS Modules
○ demoJMSmodule | Configuration | New■ type: Queue■ name: lotteryqueue■ JNDI name: jms/queue/lotteryqueue■ subdeployments: demoJMSsubmodule■ target/server: demoJMSserver
6
JMS Provider beállítása IIIConnection Factory
● Services | Messaging | JMS Modules○ demoJMSmodule | Configuration | New
■ type: Connection Factory■ name: demoConnectionFactory■ JNDI name: jms/demoConnectionFactory■ target: myserver
7
Message Driven Bean
8
@MessageDriven(name = "LotteryListener", activationConfig = { //@ActivationConfigProperty(propertyName =
"connectionFactoryJndiName", propertyValue = "jms/demoConnectionFactory"),
@ActivationConfigProperty(propertyName = "initialContextFactory", propertyValue = "weblogic.jndi.WLInitialContextFactory"),
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destinationJndiName", propertyValue = "jms/queue/lotteryqueue"),
@ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge") })public class LotteryListener implements MessageListener, MessageDrivenBean {..}
LotteryListener.java
MessageDrivenBean implementálása nem kötelező, de lehetőséget ad az MDB életciklusába való beavatkozásra (setMessageDrivenContext(..) és ejbRemove() metódusok által).
Message Driven BeanJBoss vs. WebLogic
9
Activation Config Property name
JBoss property value
WebLogic property value
Megjegyzés
connectionFactoryJndiName
jms/demoConnectionFactory
Megadása külső JMS Provider esetén érdekes (pl. ActiveMQ-t). Nem kötelező.
initialContextFactory
org.jboss.naming.remote.client.InitialContextFactory
weblogic.jndi.WLInitialContextFactory
Nem kötelező
destinationType javax.jms.Queue javax.jms.Queue Másik lehetséges érték a javax.jms.Topic
destinationJndiName
jms/queue/lotteryqueue
jms/queue/lotteryqueue
A destinationJndiName és destination közül csak egy egyik szükséges.
destination lotteryqueue - WebLogic nem támogatja, JBoss-ban van “belső rövid név”, de használható a JNDI név is!
acknowledgeMode Auto-acknowledge Auto-acknowledge WebLogic dokumentáció szerint nem veszi figyelembe. Sok helyen írják nagybetűvel (AUTO_ACKNOWLEDGE).
Remote JMS Client
10
final Properties environment = new Properties();environment.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");environment.put(Context.PROVIDER_URL, "t3://localhost:7001");environment.put(Context.SECURITY_PRINCIPAL, "weblogic");environment.put(Context.SECURITY_CREDENTIALS, "AlmafA1#");Context context = new InitialContext(environment);final ConnectionFactory connectionFactory = (ConnectionFactory) context.lookup("jms/demoConnectionFactory");final Destination destination = (Destination) context.lookup("jms/queue/lotteryqueue");Connection connection = connectionFactory.createConnection("weblogic", "AlmafA1#");final Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);final MessageProducer producer = session.createProducer(destination);connection.start();final TextMessage textMessage = session.createTextMessage("1, 2, 3, 4, 5");producer.send(textMessage);connection.close();
SimpleClient.java
Remote JMS ClientJBoss vs. WebLogic
11
JBoss WebLogic
PROVIDER URL remote://localhost:4447 t3://localhost:7001
USERNAME jmstestuser weblogic
PASSWORD User#70365 AlmafA1#
DESTINATION JNDI jms/queue/lotteryqueue jms/queue/lotteryqueue
INITIAL CONTEXT FACTORY org.jboss.naming.remote.client.InitialContextFactory
weblogic.jndi.WLInitialContextFactory
CONNECTION FACTORY JNDI jms/RemoteConnectionFactory jms/demoConnectionFactory
CLASSPATH(Initial Context Factory osztálya)
org.jboss.as:jboss-as-jms-client-bom:7.2.0.Final
[WL-HOME]\wlserver\server\lib\wlthint3client.jar
JBoss esetén külön guest user-t hoztunk létre, míg weblogic-nál az Admin user-t használhatjuk. A Connection Factory-t JBoss esetén a standalone-full.xml-ből előre konfigurálva kaptuk, míg WebLogic esetén mi hoztuk létre Admin console-on.
Internal JMS Client
12
InitialContext context = new InitialContext();QueueConnectionFactory connectionFactory = (QueueConnectionFactory) context.lookup("javax.jms.QueueConnectionFactory");QueueConnection connection = connectionFactory.createQueueConnection();QueueSession session = connection.createQueueSession(false, Session.AUTO_ACKNOWLEDGE);Queue queue = (Queue) context.lookup(" jms/queue/lotteryqueue");QueueSender sender = session.createSender(queue);TextMessage textMessage = session.createTextMessage();
connection.start();textMessage.setText(" 1, 2, 3, 4, 5");sender.send(textMessage);
sender.close();session.close();connection.close();
SendQueueServlet.java
Üzenetet küldeni container-en belül mindig egyszerűbb, lévén InitialContext-et “konfiguráció nélkül” egyszerűen elkérhetjük (hiszen már inicializálva van), illetve nem csak “remote” connection factory-kat érünk el, hanem a szabvány által definiált JNDI néven regisztrált specifikusabbakat is (pl. a példában ilyen a QueueConnectionFactory).
Java Management ExtensionsWebLogic
Hasonlóan a JBoss esetén már bemutatott példához, JMX segítségével szeretnénk beállítani az aktuális “sorsoló” személy nevét, a nyereményalapot és a nyeremény eloszlását meghatározó “szabály-vektort”.
A lényeg természetesen a példa szempontjából a monitorozás és a beavatkozás bemutatása.
13
Managed Bean készítésekezdő lépések
14
public class LotteryMonitor extends StandardMBean implements LotteryMonitorMBean, MBeanRegistration {
public LotteryMonitor() {super(LotteryMonitorMBean. class, false);
}
@Overridepublic ObjectName preRegister(MBeanServer server, ObjectName name) throws
Exception {return name;
}
@Overridepublic void postRegister(Boolean registrationDone) {}@Overridepublic void preDeregister() throws Exception {}@Overridepublic void postDeregister() {}
}
LotteryMonitor.java
Az üzleti igények, és ezáltal a LotteryMonitorMBean interface megegyezik a JBoss-os példában bemutatottal.
Fontos! Az ős (StandardMBean ) ctor-a az MBean interface osztályát várja!
A MBeanRegistration interface használata lehetővé teszi az életciklusba való beavatkozást.
MBean regisztrációja
JBoss esetén az MBean-t az EJB module jboss-service.xml leíró segítségével regisztráltuk.
WebLogic esetén “programozottan” kell a regisztrációt elvégezni, és e programozott részt szükséges az EAR weblogic-application.xml leíró segítségével láthatóvá tenni.
15
Managed Bean regisztrációjaprogramozott megoldás
16
package hu.qwaevisz.lottery.ejbservice.management;public class ApplicationMBeanLifeCycleListener extends ApplicationLifecycleListener { private static final String MBEAN_SERVER_JNDI = "java:comp/jmx/runtime"; private static final String OBJECT_PACKAGE = "hu.qwaevisz.lottery.ejbservice.management"; @Override public void postStart(ApplicationLifecycleEvent e) throws ApplicationException {
InitialContext context = new InitialContext();MBeanServer mbeanServer = MBeanServer. class.cast( context.lookup
(MBEAN_SERVER_JNDI) );LotteryMonitor mbean = new LotteryMonitor();ObjectName oname = this.buildObjectName();mbeanServer.registerMBean(mbean, oname);
} private ObjectName buildObjectName() throws MalformedObjectNameException { return new ObjectName(OBJECT_PACKAGE + ":type="+LotteryMonitor. class.getSimpleName()+",name="+LotteryMonitor. class.getSimpleName()); }
@Override public void preStop(ApplicationLifecycleEvent e) throws ApplicationException {}}
ApplicationMBeanLifeCycleListener.java
Az ApplicationLifecycleListener osztály miatt a[WL-HOME]\wlserver\server\lib\wls-api.jar-t el kell helyezni a ClassPath-on!
JBoss esetén az ObjectName a jboss-service.xml-ben volt definiálva.
Listener leírójaweblogic-application.xml
17
<?xml version="1.0" encoding="UTF-8"?><weblogic-application xmlns="http://xmlns.oracle.com/weblogic/weblogic-application">
<listener> <listener-class>hu.qwaevisz.lottery.ejbservice.management.ApplicationMBeanLifeCycleListener</listener-class> </listener></weblogic-application>
weblogic-application.xml
A weblogic-application.xml az EAR application.xml-jének conatiner specifikus párja. Ennek megfelelően az EAR META-INF könyvtárába kell elhelyezni. Ennek legegyszerűbb módja, ha a root Gradle project (EAR plugin) src/main/application könyvtárában elhelyezzük!
jconsole
Hasonlóan a JBoss-hoz, a WebLogic esetén is szükséges a jconsole classpath-ához container specifikus JAR-ok hozzáadása.
18
> jconsole -J-Djava.class.path=%JAVA_HOME%\lib\jconsole.jar;%JAVA_HOME%\lib\tools.jar;%MW_HOME%\wlserver\server\lib\wljmxclient.jar;%MW_HOME%\wlserver\server\lib\wlclient.jar -J-Djmx.remote.protocol.provider.pkgs=weblogic.management.remote -debug
A ClassPath beállításának egyszerű módja, ha lefuttatjuk a setDomainEnv.[sh|cmd] parancsot, majd ezt követően (azonos terminalban/command ablakban) a jconsole-t elindítjuk.
> [WL-HOME]/user_projects/domains/mydomain/bin/setDomainEnv.[sh|cmd]> jconsole
EJB elérése MBean osztályból
JBoss esetén ennek semmilyen akadálya nincsen, egyszerűen az @EJB annotáció segítségével inject-áljuk a megfelelő EJB-t, és már használhatjuk is. Az MBean azonosan EJB managed elem lesz (csak managed elemek esetén használható az “injectálás”).Ott, ahol ez nem érhető el, JNDI fából kell kikérnünk az EJB-t, hasonlóan mint ahogy egy remote EJB kliensből tennénk, azonban természetesen az Initial Context-et a helyi container már inicializálta számunkra.
WebLogic esetén ez utóbbit alkalmazzuk, az @EJB annotáció ott nem működik egy MBean esetén.
19
Managed Bean regisztrációjaprogramozott megoldás
20
public class LotteryMonitor extends StandardMBean implements LotteryMonitorMBean, MBeanRegistration {
private static final String LOTTERY_STATE_HOLDER_JNDI = " java:global.lottery-1.0.lot-ejbservice.lotteryState";
private LotteryStateHolder getStateHolder() {LotteryStateHolder holder = null;try {
InitialContext context = new InitialContext();holder = LotteryStateHolder. class.cast( context.lookup
(LOTTERY_STATE_HOLDER_JNDI) );} catch (NamingException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);}return holder;
}@Overridepublic String getPuller() {
LotteryStateHolder holder = this.getStateHolder()return holder != null ? holder.getCurrentPuller() : "";
}}
LotteryMonitor.java
Honnan tudjuk hogy a LotteryStateHolder Singleton EJB-nek mi a pontos JNDI neve?
WebLogic JNDI Tree
WebLogic Administration Console● Environment | Server | Configuration
○ General tab → VIEW JNDI Tree link!Deploy-olt alkalmazások EJB-inek elérése (a JNDI fa felépítése container specifikus, bár a JEE szabvány megpróbálta már szabványosítani):● java:global
○ lottery-1.0 (deployolt EAR neve (a pont miatt a browser ketté szedi))■ lot-ejbservice (az EJB module neve az EAR-on belül)
● lotteryState (az EJB name attribútuma (def: impl. osztály neve))○ Overview tab Binding Name tulajdonság értéke
21
@Singleton(mappedName = "ejb/lotteryState", name = "lotteryState")public class LotteryStateHolderImpl implements LotteryStateHolder {}
Java Management ExtensionsJBoss vs. WebLogic
22
JBoss WebLogic
MBean interface Java interface az MBean készítés szabályai szerint*.
Java interface az MBean készítés szabályai szerint*.
MBean implementáció
EJB managed Not EJB managed (JNDI lookup szükséges)
MBean regisztráció
EJB module META-INF-jében elhelyezett jboss-service.xml segíségével.
EAR csomag META-INF-jében elhelyezett weblogic-application.xml segítségével egy leszármaztatott ApplicationLifecycleListener regisztrációja.
jconsole futtatása
[JBOSS HOME]/bin/jconsole.[bat|sh]
[WL-HOME]/user_projects/domains/mydomain/bin/setDomainEnv.[sh|cmd]jconsole
*: https://docs.oracle.com/javase/tutorial/jmx/mbeans/standard.html