|
How do I create a producer pool? The following is some pseudo-code for a producer class.
class ProducerPool { static Hashmap pSets = new Hashtable(); static Hashmap inUse = new Hashtable();
QueueSender get(String contextURL, String connectionFactoryName, String destinationName) { String lookup = contextURL+"; "+connectionFactName+";"+destName; synchronized(pSets) { producer set = pSets.get(lookup); if (set != null && set not empty) qs = set.removeFirst(); } if (producer == null) { create ctx get connect factory create connection create session look up destination qs = create queue sender } synchronized(inUse) { inUse.put(qs, lookup); } return qs; }
void put(QueueSender qs) { String lookup; synchronized(inUse) { lookup = inUse.remove(p); } synchronzied(pSets) { producer set = pSets.get(lookup); if (set == null) { producer set = new producer set pSets.put(lookup, producer set); } producer set.add(qs); } } }
Note: Static classes may be garbage collected if there are no references to them, so make sure the application server has a permanent pointer to them in some manner. One way is to reference it permanently from within a servlet or EJB when they are initialized at startup. Here is an example of using the producer pool within the onMessage method. onMessage() { QueueSender qs = ProducerPool.get(...); qs.send(...); ProducerPool.put(qs); }
You can pre-populate this pool by calling it from a startup class or a load-on-start servlet class. What are pending messages in the console? Pending means the message could have been: * sent in a transaction but not committed. * received and not acknowledged. * received and not committed. * subject to a redelivery delay (as of WebLogic Server 6.1). * subject to a delivery time (as of WebLogic Server 6.1). A rolled back message remains pending until the transaction actually rolls back. Rolling it back multiple times does not cause double counting, nor does an exception that set a transaction as rollbackOnly followed by an actual rollback. Current implies messages that are not pending. Total implies total since server last started. The byte counts only consider the payload of messages which includes the properties and the body but not the header. How do I use a less than or greater than on a message selector in ejb-jar.xml? Enclose the selector in a CDATA section. That will prevent the XML parser from thinking that less than or greater than is a tag.
<jms-message-selector> <![CDATA[ JMSXAppID <> 'user' ]]> </jms-message-selector> Is it better to have more or fewer sessions for a given number of subscribers? Using N sessions for N subscribers gives you concurrency up to N simultaneous threads of execution provided you have as many threads to work with. Each Session gets its own thread as long as there are enough threads available. Otherwise, the sessions serially reuse the available threads. One session for N subscribers serializes all subscribers through that one session. If the load is heavy they may not be able to keep up without the extra threads. If you are using CLIENT_ACKNOWLEDGE, N sessions gives you N separate message streams that can be individually recovered. Having one session crosses the streams giving you less control. Match the EJB functions given below with the functionality equivalent in SQL A.) ejbStore() 1.) INSERT B.) ejbLoad() 2.) UPDATE C.) ejbCreate() 3.) SELECT a. A->1, B->2, C->3 b. A->2, B->1, C->3 c. A->3, B->2, C->1 d. A->1, B->3, C->2 e. A->2, B->3, C->1 f. A->3, B->1, C->2
Choice E is correct. When the create() method on a home interface is invoked, the container delegates the create() method call to the bean instance's matching ejbCreate() method. The ejbCreate() methods are used to initialize the instance state before record is inserted into the database. The ejbCreate() method is analogous to INSERT. The ejbStore() method is invoked just before the container the container is about to write the bean container-managed fields to the database. It is analogous to the UPDATE . The ejbLoad() is invoked just after the container has refreshed the bean container-managed files with its state from the database. It is analogous to the SELECT. Thus choice E is correct and others are not. A client invokes a method on a stateful session bean instance deployed in the WebLogic Server. While the method execution is in progress another method call arrives on the server. What will be the result? a. RemoteException is thrown if the value of concurrency-strategy property is false b. EJBException is thrown if the value of concurrency-strategy property is false c. The EJB container blocks the concurrent method call and allows it to proceed when the previous call has completed if the value of allow-concurrent-calls is true d. In all cases, RemoteException is thrown
Choice C is correct. By default, simultaneous access to a stateful session EJB results in a RemoteException. However, you can set the allow-concurrent-calls option in the WebLogic EJB deployment descriptor to specify that a stateful session bean instance will allow concurrent method calls. This access restriction on stateful session EJBs applies whether the EJB client is remote or internal to WebLogic Server. By default, allows-concurrent-calls is false. However, when this value is set to true, the EJB container blocks the concurrent method call and allows it to proceed when the previous call has completed. The concurrency-strategy element determines ejbLoad() and ejbStore() behavior for entity EJB instances. Are foreign destinations handled within foreign JMS messages? WebLogic Server JMS does not know what to do with foreign destinations that it runs into. This issue has been discussed with Sun and the JMS specification does not clearly define destinations well enough for vendors to interoperate at that level. They agree that it is sufficient not to handle foreign destinations preferably in such a way that sending/receiving still work. For WebLogic Server JMS, if you do a setJMSdestination (you should not because it is only for the provider to set it) with a foreign destination, it gets ignored (set to null). Similarly, if you do a setJMSReplyTo for a foreign destination, WebLogic Server JMS will ignore it (set it to null). What is the standard way to create threads, do initialization, etc. within the application server? Threads should generally not be created by the user directly is because things may not work correctly. User-created threads do not have some of the thread-local variables pre-set by WebLogic when it creates it's own execute threads, the associated transaction context, or the environment such as the proper class loader. The WebLogic-specific way of doing this is with a startup class or using the WebLogic Time Services. The portable way to do this is to define a load-on-startup servlet, doing the initialization in the init() method and the cleanup in the destroy() method. The servlet itself does nothing. This approach also allows for undeploy/redeploy of the application without restarting the server, including proper cleanup/initialization each time. It also providers more dynamic management of the dependent classes without restarting the server. How many messages are sent across the network for processing topic messages? If there are three subscribers for a message, for example, one of which with a selector that does not match, how many messages are sent? In WebLogic JMS 6.1, when all three consumers are in the same session, we send one copy of the message across the network for all subscribers that are not flow-controlled. Once a consumer is flow-controlled for not acknowledging enough messages, no messages are sent until flow control is eased. So, the answer is usually one, but may be two. The selection is done on the server side so a subscriber that doesn't match doesn't have to discard anything. What should an XPATH selector look like? The following is an example of an XPATH selector. Pay careful attention to the use of double and single quotes.
String selector = "JMS_BEA_SELECT('xpath', '/recipient/transport/text()') = 'email'"; tsubscriber = tsession.createSubscriber(topic, selector, false);
JMS_BEA_SELECT is a built-in function in WebLogic Server JMS SQL syntax. You put it in your selector string when you create a consumer. Note the use of single quotes around xpath, the XML tab, and the string value. How do I handle request/response using JMS? There are several approaches to handling request/response processing with JMS. * Use a temporary queue for each requestor and have the response go back to that queue. * Use the QueueRequestor class, which does the temporary queue for you, and wait for the reply, as in the following: // create temporary queue for receiving answer qrequestor = new QueueRequestor(qsession, queue); TextMessage msg = qsession.createTextMessage(); TextMessage reply = (TextMessage) qrequestor.request(msg); * Use a dedicated response topic or queue with message selectors. How do I put a message back on the queue for processing? The following are several approaches: * Use a transacted session, then rollback the session so the message will go back to the queue. * Use Session.CLIENT_ACKNOWLEDGE when creating a session, then recover the session so the message will go back to the queue. * Use a JTA transaction, then rollback the transaction so the message will go back to the queue. Is it OK to add new sessions and subscribers to a Queue or Topic Connection once it has been started? Yes, with one caveat. You may not add new subscribers/consumers to a session if it already has active async consumers. Sessions must only be accessed single-threaded as per the JMS spec. If you feel you need to do this, create a new Session and add it to that one instead. You can add receivers to a started connection. A receiver in itself is not asynchronous. You need a listener to make it asynchronous. The first creation of a receiver is always safe. If you then add a listener for that first receiver, you have to worry for any future receivers in that same session. You can create new sessions and the first receiver for that session with no worries. Once you want to create a second receiver in a session, if the first receiver has a MessageListener, you have to take care to make sure there are no other threads of execution in that session. You can do this by stopping the connection or actually creating your receiver from the onMessage routine of the first receiver. What can I do when I get java.lang.OutOfMemoryError because producers are faster than consumers? Quotas can be used to help this situation. Your sender will then receive ResourceAllocationExceptions and the server will stay up. WLS 6.X does not support paging of messages out of memory. As of WLS 6.1 SP02 or later, you can use the Message Paging feature, which can free up valuable virtual memory during peak message load periods by swapping out messages from virtual memory to persistent storage when message loads reach a specified threshold. Which of the following is NOT true about deploying EJBs in the WebLogic Server? a. The weblogic/config/examples/applications directory acts as an automatic deployment directory for EJB 2.0 .jar files and EJB .jar deployment directories b. The automatic redeployment feature of the WebLogic Server can only redeploy an EJB's implementation classes, you cannot redeploy an EJB's public interfaces c. Before deploying a packaged jar file containing uncompiled EJB classes and interfaces, we have to use weblogic.ejbc on the packaged .jar file to generate WebLogic Server container classes.
Choice C is correct because it is NOT true. A and B are true about deploying EJBs in the WebLogic server. The weblogic/config/examples/applications directory acts as an automatic deployment directory for EJB 2.0 .jar files and EJB .jar deployment directories. When you start WebLogic Server, it automatically deploys any valid EJB 2.0 .jar files or .jar directories that reside in the applications directory. WebLogic Server also checks the contents of applications every ten seconds to determine whether an EJB deployment has changed. If a deployment has changed, it is automatically redeployed using the dynamic deployment feature. If you change the contents of a compiled EJB .jar file in applications, WebLogic Server automatically attempts to redeploy the .jar using the dynamic deployment feature. Since the automatic redeployment feature uses dynamic deployment, WebLogic Server can only redeploy an EJB's implementation classes. You cannot redeploy an EJB's public interfaces. You create compiled EJB 2.0 .jar files by Compiling your EJB classes and interfaces, packaging the EJB classes and interfaces into a valid .jar file and then Using weblogic.ejbc on the .jar file to generate WebLogic Server container classes. An uncompiled EJB .jar file has the same structure as a compiled file, but you do not have to compile individual class files and interfaces and you do not have to use weblogic.ejbc on the packaged .jar file to generate WebLogic Server container classes. So C is not true. How do I debug WebLogic Server using Visual Cafe 4.1? You can install VisualCafe Enterprise Edition 4.1 and attach it to the server, pretty much as it worked for 3.X. The following are steps for debugging using VC 4.1. You may change the directory names as necessary. 1. Install it under D:\VisualCafeEE. No special options are needed. 2. Install the license under C:\Program Files\Common Files\WebGain Shared. 3. Start ddservices by selecting Start -> Programs -> WebGain Studio Professional ->Visual Cafe Enterprise Edition 4.1 -> Distributed Debugging Services -> Start DD Services (Java2 - 1.3) 4. Start WebLogic Server using debugvm.exe instead of java.exe. cd D:\bea\wlserver6.1\config\mydomain setEnv edit startWebLogic.cmd change "%JAVA_home%\bin\java" -hotspot -ms64m -mx64m to \visualcafeEE\jdk13\bin\debugvm.exe 5. Run startWebLogic. It prints out some debugging information. 6. Run VisualCafe - Start -> Programs -> WebGain Studio Professional -> Visual Cafe Enterprise Edition 4.1 -> Visual Cafe Enterprise Edition 4.1 7. From the File menu, select Attach to Process. If everything is working correctly, you should see your machine name. 8. Click the + sign to expand the tree and select your running WebLogic Server. How can I avoid asynchronous message deadlocks? Due to a limitation in the JMS 1.0.2 specification, asynchronous messages can become deadlocked if the close() method of a session is inside a user-synchronized block. To resolve this, you must move the close() method outside the user-synchronized block. For example: public class CloseTest() { private void xxx() { synchronized (this) { create connection/session/consumer initialize and set a listener for this consumer; wait(); connection.close(); } }
private void onMessage(Message message) { synchronized (this) { notify(); } } }
Before the connection.close() method is closed, another message can be delivered to the onMessage routine by the JMSProvider. The main() method thread owns the monitor lock for the CloseTest method. Before the onMessage() method of the CloseTest class fires, JMS sets INLISTENER as the state for the session in JMSSession (the JMS specification says that the close() method must wait for the onMessage routine), so that the main() method thread can wait for the onMessage routine to complete. Now when the onMessage routine tries to acquire the monitor lock, it blocks waiting for the main() method thread to give up, and the main() method thread is waiting for the onMessage to be completed. JMS also blocks when the close() method of a consumer is done from an onMessage routine and the allowCloseInOnMessage attribute is set to false in the config.xml file.
|