KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > uk > org > primrose > vendor > jboss > jndi > BindPrimrose


1 /**
2 * Library name : Primrose - A Java Database Connection Pool.
3 * Published by Ben Keeping, http://primrose.org.uk .
4 * Copyright (C) 2004 Ben Keeping, primrose.org.uk
5 * Email: Use "Contact Us Form" on website
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */

21
22 package uk.org.primrose.vendor.jboss.jndi;
23
24 import java.util.ArrayList JavaDoc;
25 import javax.naming.InitialContext JavaDoc;
26 import javax.naming.Context JavaDoc;
27 import javax.naming.NamingException JavaDoc;
28 import javax.naming.Reference JavaDoc;
29 import javax.naming.StringRefAddr JavaDoc;
30
31 import uk.org.primrose.pool.datasource.MasterPoolDataSourceFactory;
32 import uk.org.primrose.pool.datasource.PoolDataSourceFactory;
33 import uk.org.primrose.pool.jmx.MBeanUtil;
34 import uk.org.primrose.pool.jmx.PoolController;
35 import uk.org.primrose.pool.jmx.Queue;
36 import uk.org.primrose.vendor.jboss.ejb.BindHome;
37 import uk.org.primrose.vendor.jboss.ejb.Bind;
38
39 import org.jboss.naming.NonSerializableFactory;
40
41 /**
42 * This comment is on all of the vendor.jboss package classes, because the classes are
43 * so interlinked. It documents how we bind primrose under JBoss.<p>
44 * JBoss has two JNDI trees.
45 * <ul>
46 * <li>A serializable object tree.
47 * <li>A non-serializable object tree.
48 * </ul>
49 * Primrose's core jmx objects (Queue, PoolController) cannot be bound under the serializable tree
50 * because JBoss checks <i>on binding</i> whether the objects can be serialized. Because the Queue objects
51 * contain Connection objects, this will always fail.<p>
52 * So how do we get around this ?!<br>
53 * First, the MasterPoolDataSourceFactory (deployed via the SAR) initializes the pool, and binds
54 * the Queue objects, and the PoolController object under the non-serializable tree.<p>
55 * Then all the pool DataSource objects, created via the PoolDataSourceFactory's (via BindPrimrose)
56 * are all bound under the non-serializable tree.<br>
57 * Get a list of the pools bound by PoolController,
58 * and then for each one, let the PoolDataSourceFactory object
59 * create our DatSource objects, which we will bind under the non-serializable tree.
60 * Also bind our 'fake' DataSource objects under the normal JNDI tree
61 * so they can be bound, and access the real non-serializable objects at runtime
62 * for extracting client connections.<p>
63 *
64 * When client code looks up our fake DataSource object (unbeknown to them obviously), and calls
65 * the getConnection() method, our fake object gets a ref to the real DataSource from the non-serializable
66 * JNDI tree, and extracts the Connection for the client.<p>
67 *
68 * Why does this work ? <br>
69 * The serializable JNDI tree only checks for serializablity at the point of binding - not when you
70 * do lookup() calls - so as long as we can bind our fake DataSources at the primrose initialization
71 * point, it works.
72 */

73 public class BindPrimrose implements BindPrimroseMBean {
74     private String JavaDoc poolConfigFile;
75
76     /**
77     * @returns The location of the poolConfig.properties file.
78     */

79     public String JavaDoc getPoolConfigFile() {
80         return poolConfigFile;
81     }
82
83     /**
84     * @param String The location of the poolConfig.properties file.<br>
85     * Called by JBoss and set via the jboss-service.xml file as an <attribute> tag.
86     */

87     public void setPoolConfigFile(String JavaDoc poolConfigFile) {
88         this.poolConfigFile = poolConfigFile;
89     }
90
91     /**
92     * Called when JBoss unloads the MBean.
93     */

94     public void stop() {
95     }
96
97     /**
98     * This method is called when JBoss deploys the SAR, and is the entry point for binding
99     * primrose under JBoss.
100     */

101     public void start() {
102         try {
103
104             // Create our Bind EJB to bind our pools to the JNDI ENC
105
InitialContext JavaDoc ic = new InitialContext JavaDoc();
106             Object JavaDoc objRef = ic.lookup("BindBean");
107             BindHome home = (BindHome)objRef;
108             Bind binder = home.create();
109
110             // Initialize the pool and bind all objects under the non-serializable JNDI tree
111
// via the BindBean EJB
112
Reference JavaDoc ref = new Reference JavaDoc("uk.org.primrose.pool.datasource.MasterPoolDataSourceFactory");
113             String JavaDoc refType = "configFile";
114             String JavaDoc refAddr = getPoolConfigFile();
115             StringRefAddr JavaDoc sra = new StringRefAddr JavaDoc(refType, refAddr);
116             ref.add(sra);
117             MasterPoolDataSourceFactory mpdsf = new MasterPoolDataSourceFactory();
118
119             // Bind the masterPool under the non-serializable JNDI tree.
120
Object JavaDoc o = mpdsf.getObjectInstance(ref, null, null, null);
121             MBeanUtil.bind("masterPool", o);
122
123             // Bind the masterPool fake object under the same name,
124
// under the serializable JNDI tree's root (and also under ENC to be safe !).
125
FakeSerializableArrayList fsal = new FakeSerializableArrayList("masterPool");
126             binder.bindENC("masterPool", fsal);
127             binder.bindRoot("masterPool", fsal);
128
129
130             // Get a list of the pools bound by PoolController,
131
// and then for each one, let the PoolDataSourceFactory object
132
// create our DatSource objects, which we will bind under the non-serializable tree.
133
// Also bind our 'fake' DataSource objects under the normal JNDI tree
134
// so they can be bound, and access the real non-serializable objects at runtime
135
// for extracting client connections
136
ArrayList JavaDoc queues = ((PoolController)MBeanUtil.lookup("pool")).getQueues();
137             for (int i = 0; i < queues.size(); i++) {
138                 Queue q = (Queue)queues.get(i);
139                 ref = new Reference JavaDoc("uk.org.primrose.pool.datasource.PoolDataSourceFactory");
140                 refType = "poolName";
141                 refAddr = q.getName();
142                 sra = new StringRefAddr JavaDoc(refType, refAddr);
143                 ref.add(sra);
144
145                 PoolDataSourceFactory pdsf = new PoolDataSourceFactory();
146                 o = pdsf.getObjectInstance(ref, null, null, null);
147
148                 MBeanUtil.bind("java:comp/env/" +q.getName(), o);
149
150                 FakeSerializableDataSource fsds = new FakeSerializableDataSource("java:comp/env/" +q.getName());
151                 // Bind the pool via our EJB under the JNDI ENC env,
152
// and also on root (to be safe incase users don't lookup the ENC
153
binder.bindENC(q.getName(), fsds);
154                 binder.bindRoot(q.getName(), fsds);
155             }
156
157
158         } catch (Exception JavaDoc e) {
159             e.printStackTrace(System.err);
160         }
161
162    }
163 }
164
Popular Tags