Source Code Cross Referenced for JMdbEndpointFactory.java in  » J2EE » JOnAS-4.8.6 » org » objectweb » jonas_ejb » container » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » J2EE » JOnAS 4.8.6 » org.objectweb.jonas_ejb.container 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**
002:         * JOnAS: Java(TM) Open Application Server
003:         * Copyright (C) 1999-2005 Bull S.A.
004:         * Contact: jonas-team@objectweb.org
005:         *
006:         * This library is free software; you can redistribute it and/or
007:         * modify it under the terms of the GNU Lesser General Public
008:         * License as published by the Free Software Foundation; either
009:         * version 2.1 of the License, or any later version.
010:         *
011:         * This library is distributed in the hope that it will be useful,
012:         * but WITHOUT ANY WARRANTY; without even the implied warranty of
013:         * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014:         * Lesser General Public License for more details.
015:         *
016:         * You should have received a copy of the GNU Lesser General Public
017:         * License along with this library; if not, write to the Free Software
018:         * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
019:         * USA
020:         *
021:         * --------------------------------------------------------------------------
022:         * $Id: JMdbEndpointFactory.java 10144 2007-04-05 06:48:57Z durieuxp $
023:         * --------------------------------------------------------------------------
024:         */package org.objectweb.jonas_ejb.container;
025:
026:        import java.lang.reflect.Method;
027:        import java.lang.reflect.Proxy;
028:        import java.util.ArrayList;
029:        import java.util.LinkedList;
030:        import java.util.List;
031:        import java.util.ListIterator;
032:
033:        import javax.ejb.EJBException;
034:        import javax.ejb.MessageDrivenBean;
035:        import javax.ejb.MessageDrivenContext;
036:        import javax.ejb.Timer;
037:        import javax.ejb.TimerService;
038:        import javax.naming.Context;
039:        import javax.resource.spi.ActivationSpec;
040:        import javax.resource.spi.UnavailableException;
041:        import javax.resource.spi.endpoint.MessageEndpoint;
042:        import javax.resource.spi.endpoint.MessageEndpointFactory;
043:        import javax.transaction.SystemException;
044:        import javax.transaction.Transaction;
045:        import javax.transaction.xa.XAResource;
046:
047:        import org.objectweb.jotm.Current;
048:
049:        import org.objectweb.jonas_ejb.deployment.api.ActivationConfigPropertyDesc;
050:        import org.objectweb.jonas_ejb.deployment.api.MessageDrivenDesc;
051:        import org.objectweb.jonas_ejb.deployment.api.MethodDesc;
052:
053:        import org.objectweb.jonas.resource.Rar;
054:
055:        import org.objectweb.util.monolog.api.BasicLevel;
056:
057:        /**
058:         * This class is a factory for a Message Driven Bean Endpoints There is one such
059:         * class per MDB class. Contains all information related to the bean
060:         * @author Eric Hardesty
061:         */
062:        public class JMdbEndpointFactory extends JFactory implements 
063:                MessageEndpointFactory {
064:
065:            /**
066:             * pool of JMessageEndpoint objects
067:             */
068:            private List endpool = new ArrayList();
069:
070:            /**
071:             * count of the instances
072:             */
073:            private int instanceCount = 0;
074:
075:            /**
076:             *  minimum pool size
077:             */
078:            private int minPoolSize = 0;
079:
080:            /**
081:             *  maximum number of instances in the cache
082:             */
083:            private int maxCacheSize = 0;
084:
085:            /**
086:             * ActivationSpec associated with this factory
087:             */
088:            private ActivationSpec as = null;
089:
090:            /**
091:             * Message listener type
092:             */
093:            private String msglistenType = null;
094:
095:            /**
096:             * Associated RAR object
097:             */
098:            private Rar rar = null;
099:
100:            /**
101:             * activated indicator
102:             */
103:            private boolean activated = false;
104:
105:            /**
106:             * Constructor
107:             * @param dd Message Driven Descriptor
108:             * @param cont Container where this bean is defined
109:             * @param as ActivationSpec to link the Container to
110:             */
111:            public JMdbEndpointFactory(MessageDrivenDesc dd, JContainer cont,
112:                    ActivationSpec as) {
113:                super (dd, cont);
114:                String dest = dd.getDestinationJndiName();
115:                // Set the AS properties and validate the required config properties
116:                List acpl = null;
117:                if (dd.getMdActivationConfigDesc() != null) {
118:                    acpl = dd.getMdActivationConfigDesc()
119:                            .getActivationConfigPropertyList();
120:                }
121:                List jAcpl = null;
122:                if (dd.getJonasMdActivationConfigDesc() != null) {
123:                    jAcpl = dd.getJonasMdActivationConfigDesc()
124:                            .getActivationConfigPropertyList();
125:                }
126:                mdbEFInit(dd, dest, acpl, jAcpl, as);
127:            }
128:
129:            /**
130:             * Constructor
131:             * @param dd Message Driven Descriptor
132:             * @param destination String of desired destination
133:             * @param cont Container where this bean is defined
134:             * @param as ActivationSpec to link the Container to
135:             */
136:            public JMdbEndpointFactory(MessageDrivenDesc dd,
137:                    String destination, JContainer cont, ActivationSpec as) {
138:                super (dd, cont);
139:
140:                // Build Activation spec linked list from variables
141:
142:                List jAcpl = new LinkedList();
143:                List acpl = null;
144:                if (dd.getMdActivationConfigDesc() != null) {
145:                    acpl = dd.getMdActivationConfigDesc()
146:                            .getActivationConfigPropertyList();
147:                }
148:                buildACL(dd, jAcpl);
149:
150:                mdbEFInit(dd, destination, acpl, jAcpl, as);
151:            }
152:
153:            /**
154:             * Create the ActivationConfigProperty List
155:             * @param dd MessageDrivenDesc
156:             * @param jacl List to update
157:             */
158:            private void buildACL(MessageDrivenDesc dd, List jacl) {
159:
160:                String[] aclNames = { "destination", "destinationType",
161:                        "messageSelector", "acknowledgeMode",
162:                        "subscriptionDurability" };
163:
164:                ActivationConfigPropertyDesc acp = null;
165:
166:                acp = new ActivationConfigPropertyDesc();
167:                acp.setActivationConfigPropertyName("destination");
168:                acp.setActivationConfigPropertyValue(dd
169:                        .getDestinationJndiName());
170:                jacl.add(acp);
171:
172:                acp = new ActivationConfigPropertyDesc();
173:                acp.setActivationConfigPropertyName("destinationType");
174:                if (dd.isTopicDestination()) {
175:                    acp.setActivationConfigPropertyValue("javax.jms.Topic");
176:                } else {
177:                    acp.setActivationConfigPropertyValue("javax.jms.Queue");
178:                }
179:                jacl.add(acp);
180:
181:                acp = new ActivationConfigPropertyDesc();
182:                acp.setActivationConfigPropertyName("messageSelector");
183:                acp.setActivationConfigPropertyValue(dd.getSelector());
184:                jacl.add(acp);
185:
186:                acp = new ActivationConfigPropertyDesc();
187:                acp.setActivationConfigPropertyName("acknowledgeMode");
188:                if (dd.getAcknowledgeMode() == MessageDrivenDesc.AUTO_ACKNOWLEDGE) {
189:                    acp.setActivationConfigPropertyValue("Auto-acknowledge");
190:                } else {
191:                    acp.setActivationConfigPropertyValue("Dups-ok-acknowledge");
192:                }
193:                jacl.add(acp);
194:
195:                acp = new ActivationConfigPropertyDesc();
196:                acp.setActivationConfigPropertyName("subscriptionDurability");
197:                if (dd.getSubscriptionDurability() == MessageDrivenDesc.SUBS_DURABLE) {
198:                    acp.setActivationConfigPropertyValue("Durable");
199:                } else {
200:                    acp.setActivationConfigPropertyValue("NonDurable");
201:                }
202:                jacl.add(acp);
203:
204:                if (dd.getSubscriptionDurability() == MessageDrivenDesc.SUBS_DURABLE) {
205:                    acp = new ActivationConfigPropertyDesc();
206:                    acp.setActivationConfigPropertyName("subscriptionName");
207:                    acp.setActivationConfigPropertyValue(dd.getEjbName());
208:                    jacl.add(acp);
209:                }
210:
211:                // Check existing list to determine if additional items are configured, then pass them along also
212:                List acpl = null;
213:                if (dd.getJonasMdActivationConfigDesc() != null) {
214:                    acpl = dd.getJonasMdActivationConfigDesc()
215:                            .getActivationConfigPropertyList();
216:
217:                    String acpName = null;
218:                    boolean found = false;
219:                    for (int i = 0; i < acpl.size(); i++) {
220:                        acp = (ActivationConfigPropertyDesc) acpl.get(i);
221:                        acpName = acp.getActivationConfigPropertyName();
222:                        found = false;
223:                        for (int j = 0; j < aclNames.length; j++) {
224:                            if (acpName.equals(aclNames[j])) {
225:                                found = true;
226:                                break;
227:                            }
228:                        }
229:                        if (!found) {
230:                            jacl.add(acp);
231:                        }
232:                    }
233:
234:                }
235:            }
236:
237:            /**
238:             * Init this endpointfactory
239:             * @param dd Message Driven Descriptor
240:             * @param dest String destination desired
241:             * @param acpl List of activation properites
242:             * @param jAcpl List of JOnAS activation properites
243:             * @param aSpec ActivationSpec to link the Container to
244:             */
245:            private void mdbEFInit(MessageDrivenDesc dd, String dest,
246:                    List acpl, List jAcpl, ActivationSpec aSpec) {
247:
248:                String methName = "mdbEFInit: ";
249:                String ejbName = dd.getEjbName();
250:
251:                // Check if tx managed by the bean or the container
252:                txbeanmanaged = dd.isBeanManagedTransaction();
253:
254:                // Set ActivationSpec
255:                as = aSpec;
256:
257:                minPoolSize = dd.getPoolMin();
258:                maxCacheSize = dd.getCacheMax();
259:                if (TraceEjb.isDebugJms()) {
260:                    TraceEjb.mdb.log(BasicLevel.DEBUG, methName
261:                            + "maxCacheSize = " + maxCacheSize
262:                            + " minPoolSize = " + minPoolSize);
263:                }
264:
265:                // Get the associated Resource Adapter and messagelistenerType
266:                rar = Rar.getRar(dest);
267:                if (rar == null) {
268:                    TraceEjb.mdb.log(BasicLevel.ERROR, methName
269:                            + "cannot retrieve associated Resource Adapter ");
270:                    throw new EJBException(
271:                            "cannot retrieve associated Resource Adapter ");
272:                }
273:                msglistenType = rar.getInterface(dest);
274:
275:                try {
276:                    rar.configureAS(as, acpl, jAcpl, dest, ejbName);
277:                } catch (Exception ex) {
278:                    TraceEjb.mdb.log(BasicLevel.ERROR, methName
279:                            + "cannot configure activationspec " + ex);
280:                    ex.printStackTrace();
281:                    throw new EJBException("cannot configure activationspec ",
282:                            ex);
283:                }
284:
285:                // pre-allocate a set of Endpoints
286:                synchronized (endpool) {
287:                    for (int i = 0; i < minPoolSize; i++) {
288:                        JMessageEndpoint ep = null;
289:                        ep = createNewInstance();
290:                        endpool.add(ep);
291:                    }
292:                }
293:                if (minPoolSize != 0) {
294:                    TraceEjb.mdb.log(BasicLevel.INFO, methName
295:                            + "pre-allocate a set of " + minPoolSize
296:                            + " message driven bean  instances");
297:                }
298:
299:                // Call to register an XAResource with JOTM
300:                try {
301:                    ActivationSpec[] asArray = new ActivationSpec[1];
302:                    asArray[0] = as;
303:                    XAResource[] xar = rar.getResourceAdapter().getXAResources(
304:                            asArray);
305:                    if (xar != null && xar.length > 0) {
306:                        Current.getTransactionRecovery()
307:                                .registerResourceManager(
308:                                        ejbName + msglistenType, xar[0], "",
309:                                        null);
310:                    }
311:                } catch (Exception ex) {
312:                    TraceEjb.mdb.log(BasicLevel.ERROR, ex.getMessage(), ex);
313:                }
314:
315:                activated = true;
316:                // EndpointActivation
317:                try {
318:                    rar.getResourceAdapter().endpointActivation(this , as);
319:                } catch (Exception ex) {
320:                    activated = false;
321:                    TraceEjb.mdb.log(BasicLevel.ERROR, methName
322:                            + "cannot activate endpoint ", ex);
323:                    throw new EJBException("cannot activate endpoint ", ex);
324:                }
325:            }
326:
327:            // ---------------------------------------------------------------
328:            // Specific BeanFactory implementation
329:            // ---------------------------------------------------------------
330:
331:            /**
332:             * Init pool of instances
333:             */
334:            public void initInstancePool() {
335:            }
336:
337:            /**
338:             * @return the size of the EndpointPool
339:             */
340:            public int getPoolSize() {
341:                return endpool.size();
342:            }
343:
344:            /**
345:             * stop this EJB. call deactivate on the Endpoint Stop the threads and
346:             * remove the beans
347:             */
348:            public void stop() {
349:                String methName = "stop: ";
350:                if (TraceEjb.isDebugJms()) {
351:                    TraceEjb.mdb.log(BasicLevel.DEBUG, methName);
352:                }
353:                try {
354:                    // Deactivate the endpoint
355:                    rar.getResourceAdapter().endpointDeactivation(this , as);
356:                    // Loop thru the endpool and release them
357:                    synchronized (endpool) {
358:                        if (TraceEjb.isDebugJms()) {
359:                            TraceEjb.mdb.log(BasicLevel.DEBUG, methName
360:                                    + "stopping " + this );
361:                        }
362:                        JMessageEndpoint ep = null;
363:                        while (endpool.size() > 0) {
364:                            ep = (JMessageEndpoint) endpool.remove(0);
365:                            instanceCount--;
366:                            try {
367:                                ep.mdb.ejbRemove();
368:                            } catch (Exception e) {
369:                                TraceEjb.mdb.log(BasicLevel.ERROR, methName
370:                                        + "Cannot remove mdb: " + ep.mdb, e);
371:                            }
372:                        }
373:                    }
374:                } catch (Exception e) {
375:                    TraceEjb.mdb.log(BasicLevel.WARN, methName
376:                            + "Cannot deactivate the endpoint", e);
377:                }
378:                stopContainer();
379:            }
380:
381:            /**
382:             * synchronize bean instances if needed
383:             */
384:            public void syncDirty(boolean notused) {
385:            }
386:
387:            /**
388:             * @return the home if exist
389:             */
390:            public JHome getHome() {
391:                return null;
392:            }
393:
394:            /**
395:             * @return the local home if exist
396:             */
397:            public JLocalHome getLocalHome() {
398:                return null;
399:            }
400:
401:            // ---------------------------------------------------------------
402:            // MessageEndpointFactory implementation
403:            // ---------------------------------------------------------------
404:
405:            /**
406:             * Create the message endpoint
407:             *
408:             * @param xaResource XAResource object to attach
409:             * @return MessageEndpoint to deliver messages to
410:             * @throws UnavailableException exception to throw
411:             */
412:            public MessageEndpoint createEndpoint(XAResource xaResource)
413:                    throws UnavailableException {
414:                String methName = "createEndpoint: ";
415:                if (TraceEjb.isDebugJms()) {
416:                    TraceEjb.mdb.log(BasicLevel.DEBUG, methName);
417:                }
418:
419:                if (!activated) {
420:                    TraceEjb.mdb
421:                            .log(
422:                                    BasicLevel.ERROR,
423:                                    methName
424:                                            + "mdb is not usuable either initial deployment or undeployment ");
425:                    throw new UnavailableException(
426:                            "mdb is not usuable either initial deployment or undeployment ");
427:                }
428:
429:                JMessageEndpoint ep = null;
430:                try {
431:                    ep = getNewInstance(xaResource);
432:                } catch (Exception ex) {
433:                    TraceEjb.mdb.log(BasicLevel.ERROR, methName
434:                            + "cannot create an endpoint ");
435:                    throw new UnavailableException(
436:                            "cannot create an endpoint ", ex);
437:                }
438:                return ep.mep;
439:            }
440:
441:            /**
442:             * Determine if the method is transacted
443:             *
444:             * @param method Method to check
445:             * @return boolean whether the specified method is transacted
446:             * @throws NoSuchMethodException exception to throw
447:             */
448:            public boolean isDeliveryTransacted(Method method)
449:                    throws NoSuchMethodException {
450:                int txAttribute = 0;
451:                try {
452:                    txAttribute = dd.getMethodDesc(method).getTxAttribute();
453:                } catch (Exception ex) {
454:                    TraceEjb.mdb.log(BasicLevel.ERROR,
455:                            "isDeliveryTransacted: No such method exists. "
456:                                    + method.getName(), ex);
457:                    throw new NoSuchMethodException("No such method exists. "
458:                            + method.getName());
459:                }
460:                return (txAttribute == MethodDesc.TX_REQUIRED);
461:            }
462:
463:            // ---------------------------------------------------------------
464:            // Other methods
465:            // ---------------------------------------------------------------
466:
467:            /**
468:             * Return an MessageEndpoint from the pool. If pool is empty, creates a new
469:             * one.
470:             * @return an MessageEndpoint from the pool.
471:             * @exception Exception - if an application server fails to return an
472:             *            MessageEndpoint out of its pool.
473:             */
474:            public JMessageEndpoint getMessageEndpoint() throws Exception {
475:                if (TraceEjb.isDebugJms()) {
476:                    TraceEjb.mdb.log(BasicLevel.DEBUG, "getMessageEndpoint: ");
477:                }
478:
479:                return getNewInstance(null);
480:            }
481:
482:            /**
483:             * put the JMessageEndpoint back to the pool
484:             * @param ep the MessageEndpoint
485:             */
486:            public void releaseEndpoint(JMessageEndpoint ep) {
487:                String methName = "releaseEndpoint: ";
488:                if (TraceEjb.isDebugJms()) {
489:                    TraceEjb.mdb.log(BasicLevel.DEBUG, methName + ep);
490:                }
491:
492:                ep.setReleasedState(true);
493:                synchronized (endpool) {
494:                    endpool.add(ep);
495:                    if (TraceEjb.isDebugJms()) {
496:                        TraceEjb.mdb.log(BasicLevel.DEBUG, methName
497:                                + "notifyAll ");
498:                    }
499:                    endpool.notifyAll();
500:                }
501:                if (TraceEjb.isDebugJms()) {
502:                    TraceEjb.mdb.log(BasicLevel.DEBUG, methName
503:                            + "nb instances " + getCacheSize());
504:                    TraceEjb.mdb.log(BasicLevel.DEBUG, methName
505:                            + "nb free cached instances " + getPoolSize());
506:                }
507:
508:            }
509:
510:            // ---------------------------------------------------------------
511:            // other public methods
512:            // ---------------------------------------------------------------
513:
514:            /**
515:             * Obtains the TimerService associated for this Bean
516:             * @return a JTimerService instance.
517:             */
518:            public TimerService getTimerService() {
519:                if (myTimerService == null) {
520:                    // TODO : Check that instance implements TimedObject ?
521:                    myTimerService = new JTimerService(this );
522:                }
523:                return myTimerService;
524:            }
525:
526:            /**
527:             * @return min pool size for Jmx
528:             */
529:            public int getMinPoolSize() {
530:                return minPoolSize;
531:            }
532:
533:            /**
534:             * @return max cache size for Jmx
535:             */
536:            public int getMaxCacheSize() {
537:                return maxCacheSize;
538:            }
539:
540:            /**
541:             * @return current cache size ( = nb of instance created) for Jmx
542:             */
543:            public int getCacheSize() {
544:                return instanceCount;
545:            }
546:
547:            /**
548:             * @return the Transaction Attribute
549:             */
550:            public int getTransactionAttribute() {
551:                return ((MessageDrivenDesc) dd).getTxAttribute();
552:            }
553:
554:            /**
555:             * For Message Driven Beans, only 2 cases are possible:
556:             * TX_REQUIRED or TX_NOT_SUPPORTED
557:             * @param rctx The Request Context
558:             */
559:            public void checkTransaction(RequestCtx rctx) {
560:                String methName = "checkTransaction: ";
561:                if (rctx.txAttr == MethodDesc.TX_REQUIRED) {
562:                    try {
563:                        if (txbeanmanaged) {
564:                            if (tm.getTransaction() == null) {
565:                                TraceEjb.mdb.log(BasicLevel.ERROR, methName
566:                                        + "No transaction and need one");
567:                                return;
568:                            }
569:                        } else {
570:                            if (tm.getTransaction() == null) {
571:                                tm.begin();
572:                            }
573:                        }
574:                        rctx.mustCommit = true;
575:                        rctx.currTx = tm.getTransaction();
576:                        if (TraceEjb.isDebugTx()) {
577:                            TraceEjb.tx.log(BasicLevel.DEBUG,
578:                                    "Transaction started: " + rctx.currTx);
579:                        }
580:                    } catch (Exception e) {
581:                        // No exception raised in case of MDB
582:                        TraceEjb.mdb.log(BasicLevel.ERROR, methName
583:                                + "cannot start tx:", e);
584:                        return;
585:                    }
586:                } else {
587:                    if (rctx.txAttr != MethodDesc.TX_NOT_SUPPORTED) {
588:                        TraceEjb.mdb.log(BasicLevel.ERROR, methName
589:                                + "Bad transaction attribute: " + rctx.txAttr);
590:                    }
591:                    try {
592:                        rctx.currTx = tm.getTransaction();
593:                        if (rctx.currTx != null) {
594:                            if (TraceEjb.isDebugJms()) {
595:                                TraceEjb.mdb.log(BasicLevel.DEBUG, methName
596:                                        + "Suspending client tx");
597:                            }
598:                            rctx.clientTx = tm.suspend();
599:                            rctx.currTx = null;
600:                        }
601:                    } catch (SystemException e) {
602:                        TraceEjb.mdb.log(BasicLevel.ERROR, methName
603:                                + "cannot suspend transaction", e);
604:                        return;
605:                    }
606:                }
607:            }
608:
609:            /**
610:             * Reduce number of instances in memory in the free list we reduce to the
611:             * minPoolSize
612:             */
613:            public void reduceCache() {
614:                String methName = "reduceCache: ";
615:                if (TraceEjb.isDebugJms()) {
616:                    TraceEjb.mdb.log(BasicLevel.DEBUG, methName);
617:                }
618:                // reduce the pool to the minPoolSize
619:                int poolsz = minPoolSize;
620:                synchronized (endpool) {
621:                    if (TraceEjb.isDebugJms()) {
622:                        TraceEjb.mdb.log(BasicLevel.DEBUG, methName
623:                                + "try to reduce " + endpool.size() + " to "
624:                                + poolsz);
625:                    }
626:                    while (endpool.size() > poolsz) {
627:                        ListIterator i = endpool.listIterator();
628:                        if (i.hasNext()) {
629:                            i.next();
630:                            i.remove();
631:                            instanceCount--;
632:                        }
633:                    }
634:                }
635:                if (TraceEjb.isDebugJms()) {
636:                    TraceEjb.mdb.log(BasicLevel.DEBUG, methName + "cacheSize= "
637:                            + getCacheSize());
638:                }
639:
640:            }
641:
642:            /**
643:             * Notify a timeout for this bean
644:             * @param timer timer whose expiration caused this notification.
645:             */
646:            public void notifyTimeout(Timer timer) {
647:                if (stopped) {
648:                    TraceEjb.mdb.log(BasicLevel.WARN, "Container stopped");
649:                    return;
650:                }
651:                String methName = "notifyTimeout: ";
652:                if (TraceEjb.isDebugJms()) {
653:                    TraceEjb.mdb.log(BasicLevel.DEBUG, methName);
654:                }
655:
656:                // We need an instance from the pool to process the timeout.
657:                JMessageEndpoint ep = null;
658:                try {
659:                    ep = getNewInstance(null);
660:                } catch (Exception e) {
661:                    TraceEjb.mdb.log(BasicLevel.ERROR, methName + "exception:"
662:                            + e);
663:                    throw new EJBException("Cannot deliver the timeout", e);
664:                }
665:
666:                // deliver the timeout to the bean
667:                ep.deliverTimeout(timer);
668:
669:                // release the instance
670:                releaseEndpoint(ep);
671:            }
672:
673:            // ---------------------------------------------------------------
674:            // private methods
675:            // ---------------------------------------------------------------
676:
677:            /**
678:             * return a new instance of the bean. Try to get one from the pool, and
679:             * create a new one if the pool is empty.
680:             *
681:             * @param xaResource XAResource to use
682:             * @return JMessageEndpoint to return
683:             * @throws Exception to throw
684:             */
685:            private JMessageEndpoint getNewInstance(XAResource xaResource)
686:                    throws Exception {
687:                String methName = "getNewInstance: ";
688:                if (TraceEjb.isDebugJms()) {
689:                    TraceEjb.mdb.log(BasicLevel.DEBUG, methName + "Factory: "
690:                            + this  + " XAResource: " + xaResource);
691:                }
692:
693:                // try to get one from the Pool
694:                JMessageEndpoint ep = null;
695:
696:                // try to find a free entry in the pool
697:                synchronized (endpool) {
698:                    if (!endpool.isEmpty()) {
699:                        try {
700:                            ep = (JMessageEndpoint) endpool.remove(0);
701:                        } catch (Exception ex) {
702:                            // This should never happen
703:                            TraceEjb.mdb.log(BasicLevel.ERROR, methName
704:                                    + "Exception:" + ex);
705:                            throw new EJBException(
706:                                    "Cannot get an instance from the pool", ex);
707:                        }
708:                    } else {
709:                        if (TraceEjb.isDebugJms()) {
710:                            TraceEjb.mdb.log(BasicLevel.DEBUG, methName
711:                                    + "pool is empty");
712:                        }
713:                        if (maxCacheSize == 0 || instanceCount < maxCacheSize) {
714:                            // Pool has free slots, create a new MessageEndpoint object
715:                            ep = createNewInstance();
716:                        } else {
717:                            while (endpool.isEmpty()) {
718:                                if (TraceEjb.isDebugJms()) {
719:                                    TraceEjb.mdb
720:                                            .log(
721:                                                    BasicLevel.DEBUG,
722:                                                    methName
723:                                                            + "endpool.isEmpty() = true --> wait()");
724:                                }
725:                                try {
726:                                    endpool.wait();
727:                                    if (TraceEjb.isDebugJms()) {
728:                                        TraceEjb.mdb.log(BasicLevel.DEBUG,
729:                                                methName + "endpool notified");
730:                                    }
731:                                } catch (InterruptedException e) {
732:                                    if (TraceEjb.isDebugJms()) {
733:                                        TraceEjb.mdb
734:                                                .log(
735:                                                        BasicLevel.DEBUG,
736:                                                        methName
737:                                                                + "endpool waiting interrupted",
738:                                                        e);
739:                                    }
740:                                } catch (Exception e) {
741:                                    throw new EJBException(
742:                                            "synchronization pb", e);
743:                                }
744:                            }
745:                            try {
746:                                ep = (JMessageEndpoint) endpool.remove(0);
747:                            } catch (Exception ex) {
748:                                // This should never happen
749:                                TraceEjb.mdb.log(BasicLevel.ERROR, methName
750:                                        + "Exception:" + ex);
751:                                throw new EJBException(
752:                                        "Cannot get an instance from the pool",
753:                                        ex);
754:                            }
755:                        }
756:
757:                    }
758:                    if (TraceEjb.isDebugJms()) {
759:                        TraceEjb.mdb.log(BasicLevel.DEBUG, methName
760:                                + "nb instances " + getCacheSize());
761:                    }
762:                    ep.setXAResource(xaResource);
763:                    ep.setReleasedState(false);
764:                    if (TraceEjb.isDebugJms()) {
765:                        TraceEjb.mdb.log(BasicLevel.DEBUG, methName
766:                                + "Returning " + ep);
767:                    }
768:                    return ep;
769:                }
770:            }
771:
772:            /**
773:             * Create a new instance of the bean
774:             *
775:             * @return JMessageEndpoint to return
776:             */
777:            private JMessageEndpoint createNewInstance() {
778:                String methName = "createNewInstance: ";
779:                if (TraceEjb.isDebugJms()) {
780:                    TraceEjb.mdb.log(BasicLevel.DEBUG, methName);
781:                }
782:                JMessageEndpointProxy epProxy = null;
783:                MessageEndpoint ep = null;
784:                JMessageEndpoint jep = null;
785:                ClassLoader cls = myClassLoader();
786:
787:                // Set ContextClassLoader with the ejbclassloader.
788:                // This is necessary in case ejbCreate calls another bean in the same
789:                // jar.
790:                ClassLoader old = Thread.currentThread()
791:                        .getContextClassLoader();
792:                Thread.currentThread().setContextClassLoader(cls);
793:
794:                // Creates the new instance
795:                MessageDrivenBean mdb = null;
796:                try {
797:                    mdb = (MessageDrivenBean) beanclass.newInstance();
798:                } catch (Exception e) {
799:                    TraceEjb.mdb.log(BasicLevel.ERROR, methName
800:                            + "failed to create instance:", e);
801:                    resetToOldClassLoader(old);
802:                    throw new EJBException(
803:                            "Container failed to create instance of Message Driven Bean",
804:                            e);
805:                }
806:
807:                // Instanciates a new JMessageEndpoint object
808:                jep = new JMessageEndpoint(this , mdb);
809:                epProxy = new JMessageEndpointProxy(this , mdb, jep);
810:                Class msgListenerClass = null;
811:                try {
812:                    msgListenerClass = cls.loadClass(msglistenType);
813:                } catch (ClassNotFoundException e) {
814:                    String error = "Container failed to load class of Message Driven Bean '"
815:                            + msglistenType + "'";
816:                    TraceEjb.mdb.log(BasicLevel.ERROR, error, e);
817:                    resetToOldClassLoader(old);
818:                    throw new EJBException(error, e);
819:                }
820:                ep = (MessageEndpoint) Proxy.newProxyInstance(cls, new Class[] {
821:                        MessageEndpoint.class, msgListenerClass }, epProxy);
822:
823:                jep.setProxy(ep);
824:                // starts the bean instance: setMessageDrivenContext() + ejbCreate()
825:                // see EJB spec. 2.0 page 322.
826:                // Both operations must be called with the correct ComponentContext
827:                Context ctxsave = setComponentContext();
828:                mdb.setMessageDrivenContext((MessageDrivenContext) jep);
829:                try {
830:                    Method m = beanclass.getMethod("ejbCreate", (Class[]) null);
831:
832:                    boolean bm = m.isAccessible();
833:                    if (!bm) {
834:                        m.setAccessible(true);
835:                    }
836:                    m.invoke(mdb, (Object[]) null);
837:                    m.setAccessible(bm);
838:                } catch (Exception e) {
839:                    TraceEjb.mdb
840:                            .log(
841:                                    BasicLevel.ERROR,
842:                                    methName
843:                                            + " cannot call ejbCreate on message driven bean instance ",
844:                                    e);
845:                    throw new EJBException(
846:                            "Container fails to call ejbCreate on message driven bean instance",
847:                            e);
848:                } finally {
849:                    resetToOldClassLoader(old);
850:                    resetComponentContext(ctxsave);
851:                }
852:
853:                synchronized (endpool) {
854:                    instanceCount++;
855:                }
856:                return jep;
857:            }
858:
859:            /**
860:             * Reset currentThread context ClassLoader to a given ClassLoader
861:             * @param old Old ClassLoader to reuse
862:             */
863:            private void resetToOldClassLoader(ClassLoader old) {
864:                if (old != null) {
865:                    Thread.currentThread().setContextClassLoader(old);
866:                }
867:            }
868:
869:            /*
870:             * Make sense only for entities
871:             */
872:            public void storeInstances(Transaction tx) {
873:                // unused
874:
875:            }
876:
877:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.