【IT168 技术文章】
引言
J2EE连接器(JCA)是一种企业级应用整合的技术。目前,在J2EE平台中,常使用的应用整合的技术有:
Java消息服务(JMS);
Web服务(Web Services);
J2EE 连接器体系结构(JCA)。
Java消息服务是一组在Java程序中使用企业级消息的API,它为整合J2EE应用和非J2EE应用程序提供了异步整合的方式,在这种方式里,所有的应用都和消息中间件(MOM)进行通信,这样就提供了与平台无关、语言无关的整合。Web服务是一种新兴发展起来的技术,它使用SOAP消息作为传输的载体,使用HTTP或者其它基于文本的协议作为数据传输的协议,Web服务可以是同步的整合,也可以进行异步的整合。同样,Web服务也是一种和平台无关、和开发语言无关的整合技术。
J2EE连接器技术为连接J2EE应用服务器和已有的企业应用系统(ERP/CRM等)提供了解决方案。通过J2EE连接器,EIS(企业信息系统)厂商不需要再为每个应用服务器提供专门的支持接口,同样,应用服务器厂商在连接到新的EIS系统时也不需要再重新开发新的代码,JCA为整合企业资源提供了标准的解决方案。
在JCA1.0规范中,它定义了应用服务器和资源适配器的系统级合同(连接池、事务管理和安全),为资源适配器的客户端定义了通用的客户端接口(Common Client Interface,CCI),同样也规范了JCA打包和部署等细节。但在JCA1.0规范中,只支持OutBound的调用,也就是说只能在J2EE应用中通过资源适配器向外调用企业资源层,而企业资源层不能通过适配器调用J2EE里的资源。在即将发布的JCA1.5规范中,这个问题得到了解决,也就是说,在J2EE的外部可以通过资源适配器直接调用部署在J2EE中的应用,如EJB。
下面简单看一下JCA的体系结构,如图1所示。
图1 JCA的体系结构
下面解释一下上图中的一些概念。
资源适配器(Resource Adapter):为了获得在应用服务器和EIS之间的系统标准可插入性,JCA定义了应用服务器和EIS之间的一系列合约(Contract),资源适配器实现了EIS端的系统级合约。
系统级合同(System Contract):系统级合同定义了一组系统合同,可以让应用服务器和资源适配器连接起来以管理连接、事务和安全性。这样,应用组件的开发者就可以把精力集中与和业务逻辑相关的开发,而没有必要关心系统级的问题。
客户通用接口(CCI):定义了J2EE组件连接到EIS系统的一组通用的API,这些API在具体的开发中进行实现。
在连接器的开发中,主要任务就是开发资源适配器。如果需要,再开发出一套客户通用接口实现(CCI),这样,客户端就可以通过这些通用的接口来连接、使用EIS层的资源了。
在使用连接池的情况下,应用程序组件和JCA以及EIS交互关系如图2所示。
图2 应用程序组件和JCA以及EIS交互之间的交互关系
我们简要看一下请求传递的顺序:
应用程序组件发出获得连接的请求;
连接工厂调用连接管理器的allocateConnection;
连接管理器向连接池管理器发出获得连接的请求;
连接池管理器试图从ManagedConnectionFactory进行连接匹配,如果没有匹配到连接,那么返回null;
由于没有匹配到连接,连接池管理器调用ManagedConnectionFactory的createManagedConnection方法来创建连接;
ManagedConnectionFactory接收到连接池管理器的请求后,创建一个ManagedConnection实例,同时ManagedConnection打开和EIS之间的物理连接,然后把这个ManagedConnection实例返回给连接池管理器;
连接池管理器调用ManagedConnection实例的getConnection方法以获得一个Connection实例;
ManagedConnection实例收到连接池管理器的getConnection请求后,创建一个Connection实例,然后把这个实例返回给连接池管理器;
这个Connection实例通过连接池管理顺次返回给应用程序组件;
应用程序组件通过返回的Connection来创建Interaction或者调用业务方法;
应用程序组件通过Connection调用业务方法时,实际上Connection使用了ManagedConnection的物理连接和EIS进行交互。
下面我们介绍一个简单的案例的开发。
案例介绍
这个案例使用了典型的J2EE多层体系结构,如图3所示。EIS层是一个简单的能处理多线程的Socket服务程序,当它接收到客户端发送来的字符串时,就在这个字符串前增加"Hello:"字符串,然后返回。资源适配器用于连接到EIS,使得J2EE应用(如EJB)能够通过它调用EIS层。这个案例的客户端有两种,一种是基于浏览器的客户端,它通过HTTP来访问Web服务器上的JSP组件,JSP组件通过RMI调用EJB来访问EIS;另一种客户端是普通的Java程序,它通过RMI来调用部署在EJB服务器中的EJB组件以访问EIS。
图3 案例体系结构
下面我们看简单资源层的代码。
开发简单资源层
资源层是一个Socket服务程序,当它接收到客户端发送来的字符串时,就在这个字符串前增加"Hello:"字符串,然后返回这个新的字符串。代码如例程1所示。
例程1 EIS资源层
2 import java.net.*;
3 import java.io.*;
4 public class EISServer
5 {
6 public static void main(String[] args)
7 {
8 try
9 {
10 System.out.println ("启动服务....");
11 ServerSocket s = new ServerSocket (2008);
12 // 处理客户端请求
13 while (true)
14 {
15 System.out.println ("监听客户端连接...");
16 new ServerThread(s.accept()).start();
17 System.out.println ("接收到一个连接");
18 }
19 }
20 catch(Exception e)
21 {
22 e.printStackTrace(System.err);
23 }
24 }
25 }
26
27 class ServerThread extends Thread
28 {
29 private Socket socket=null;
30 public ServerThread(Socket socket)
31 {
32 super("a new thread");
33 this.socket=socket;
34 }
35 public void run()
36 {
37 try
38 {
39 BufferedReader in = new BufferedReader
40 (new InputStreamReader (socket.getInputStream()));
41 PrintStream out = new PrintStream(socket.getOutputStream());
42 String line;
43 do
44 {
45 line = in.readLine();
46 System.out.println ("接收到以下输入: " + line);
47 if (line != null)
48 {
49 out.println ("Hello: "+line);
50 }
51 } while (line != null);
52 System.out.println ("关闭连接");
53 socket.close();
54 }
55 catch(Exception e)
56 {
57 e.printStackTrace();
58 }
59 }
60 }
61
资源适配器的开发
开发资源适配器,我们从最基本的连接(Connection)类开始。
DemoConnection
DemoConnection扩展了CCI的Connection接口,它由客户端程序使用,代表了到EIS的"虚拟"连接,通过这个"虚拟"的连接客户端可以调用EIS。需要注意的是,虚拟连接关闭时,物理连接不一定关闭。DemoConnection定义了资源适配器所实现的业务方法。如例程2所示。
例程2 DemoConnection的代码
2 import javax.resource.cci.Connection;
3 import javax.resource.ResourceException;
4 public interface DemoConnection extends Connection
5 {
6 //业务方法
7 public String sayHello(String name)throws ResourceException;
8 }
9
DemoConnectionImpl
DemoConnectionImpl是DemoConnection的实现类,它通过ManagedConnection来完成具体的业务方法。ManagedConnection是代表到EIS的物理连接,将在后面介绍。
例程3 DemoConnectionImpl大代码
2 import javax.resource.*;
3 import javax.resource.spi.*;
4 import javax.resource.cci.*;
5 import javax.security.auth.*;
6 import java.util.*;
7 import java.io.*;
8 //连接实现类,它通过DemoManagedConnection来完成具体的任务
9 public class DemoConnectionImpl implements DemoConnection
10 {
11 protected PrintWriter out;//logOut
12 protected DemoManagedConnection demoManagedConnection;
13
14 //关闭连接,释放资源
15 public void close()
16 {
17 if (demoManagedConnection == null) return;
18 demoManagedConnection.removeConnection(this);
19 demoManagedConnection.connectionClosedEvent();
20 demoManagedConnection = null;
21 }
22 //返回和这个连接关联的被管理连接
23 public DemoManagedConnection getManager()
24 {
25 return demoManagedConnection;
26 }
27 //设置和这个连接关联的被管理连接
28 public void setManager (DemoManagedConnection manager)
29 {
30 this.demoManagedConnection =manager;
31 }
32
33 //业务方法,它通过调用被管理的连接来实现。
34 public String sayHello(String name)throws ResourceException
35 {
36 return demoManagedConnection.sayHello (name);
37 }
38
39 //使连接无效
40 public void invalidate()
41 {
42 demoManagedConnection = null;
43 }
44 public void setLogWriter(PrintWriter out)
45 {
46 this.out = out;
47 }
48
49 public PrintWriter getLogWriter()
50 {
51 return out;
52 }
53
54 public ConnectionMetaData getMetaData()
55 {
56 return null;
57 }
58 public ResultSetInfo getResultSetInfo()
59 {
60 return null;
61 }
62 public javax.resource.cci.LocalTransaction getLocalTransaction()
63 {
64 return null;
65 }
66 public Interaction createInteraction()
67 {
68 return null;
69 }
70
71 }
72
DemoConnectionFactoryImpl
DemoConnectionFactoryImpl也是和CCI相关的类,它实现了ConnectionFactory接口,它主要用于创建客户端要使用的虚拟连接(DemoConnection)。由于DemoConnectionFactoryImpl类需要在JNDI名字空间中注册,故它需实现Serializable和Referenceable接口。客户端查找DemoConnectionFactoryImpl类,然后使用这个类来获得到EIS的连接。DemoConnectionFactoryImpl代码如例程4所示。
例程4 DemoConnectionFactoryImpl的代码
2 import javax.resource.*;
3 import javax.resource.spi.*;
4 import javax.resource.cci.*;
5 import javax.naming.*;
6 import java.io.*;
7 public class DemoConnectionFactoryImpl implements ConnectionFactory
8 {
9 protected Reference reference;
10 protected ManagedConnectionFactory manager;
11 protected ConnectionManager connectionManager;
12 protected PrintWriter out;//logOut
13
14 //构造方法
15 public DemoConnectionFactoryImpl (ManagedConnectionFactory manager,
16 ConnectionManager connectionManager)
17 {
18 this.manager = manager;
19 //如果连接管理器为空,那么创建一个新的连接管理器
20 if (connectionManager == null)
21 {
22 connectionManager = new DemoConnectionManager();
23 ((DemoConnectionManager)connectionManager).setLogWriter (out);
24 }
25 else
26 {
27 this.connectionManager = connectionManager;
28 }
29 }
30 //获得一个连接
31 public Connection getConnection() throws ResourceException
32 {
33 return (DemoConnection)
34 connectionManager.allocateConnection (manager, null);
35 }
36 //不支持此方法
37 public Connection getConnection(ConnectionSpec p) throws ResourceException
38 {
39 return null;
40 }
41 public void setReference(Reference ref)
42 {
43 reference = ref;
44 }
45 public Reference getReference()
46 {
47 return reference;
48 }
49
50 public void setLogWriter(PrintWriter _out)
51 {
52 out = _out;
53 }
54
55 public PrintWriter getLogWriter()
56 {
57 return out;
58 }
59 public RecordFactory getRecordFactory() throws ResourceException
60 {
61 return null;
62 }
63 public ResourceAdapterMetaData getMetaData()
64 {
65 return null;
66 }
67 }
68
69
DemoConnectionManager
DemoConnectionManager是连接的管理器,它为资源适配器把连接请求传递给应用服务器提供了一个切入点。应用服务器实现DemoConnectionManager接口,这个实现不针对具体的资源适配器和连接工厂接口。DemoConnectionManager的任务就是分配连接。对于一些高级的应用,DemoConnectionManager通过和连接池交互来分配连接,在我们开发的这个案例中,DemoConnectionManager直接使用ManagedConnectionFactory来分配连接。ManagedConnectionFactory的代码如例程5所示。
例程5 ManagedConnectionFactory的代码
2 import java.io.Serializable;
3 import java.io.PrintWriter;
4 import javax.resource.ResourceException;
5 import javax.resource.spi.*;
6 public class DemoConnectionManager
7 implements ConnectionManager, Serializable
8 {
9 protected PrintWriter out;
10 //分配一个连接
11 public Object allocateConnection (ManagedConnectionFactory managedConnectionFactory,
12 ConnectionRequestInfo connectionRequestInfo)
13 throws ResourceException
14 {
15 ManagedConnection managedConnection =
16 managedConnectionFactory.createManagedConnection(null, connectionRequestInfo);
17 return managedConnection.getConnection(null, connectionRequestInfo);
18 }
19 public void setLogWriter(java.io.PrintWriter out)
20 {
21 this.out =out;
22 }
23 }
24
25
DemoManagedConnectionMetaData
DemoManagedConnectionMetaData提供了和ManagedConnection关联的后台EIS实例的信息。应用服务器通过这个接口来获得与它连接的EIS实例的运行环境信息。DemoManagedConnectionMetaData的代码如例程6所示。
例程6 DemoManagedConnectionMetaData的代码
2 import javax.resource.spi.*;
3 public class DemoManagedConnectionMetaData
4 implements ManagedConnectionMetaData
5 {
6 protected DemoManagedConnection demoManagedConnection;
7
8 public DemoManagedConnectionMetaData (DemoManagedConnection demoManagedConnection)
9 {
10 this.demoManagedConnection = demoManagedConnection;
11 }
12 //获得EIS的提供商
13 public String getEISProductName()
14 {
15 return "Hellking's Simple EIS server";
16 }
17 //获得EIS产品的版本
18 public String getEISProductVersion()
19 {
20 return "Version 1.2";
21 }
22 //eis支持的最大连接数
23 public int getMaxConnections()
24 {
25 return 10000;
26 }
27 public String getUserName()
28 {
29 return "Hellking";
30 }
31 }
32
DemoManagedConnection
DemoManagedConnection是资源适配器的关键所在,它代表了和EIS的物理连接,前面介绍的DemoConnection是由客户端使用的虚拟连接,虚拟连接要通过物理连接才能使用EIS。一个物理连接可以被多个虚拟连接使用,可以通过associateConnection方法来把虚拟连接和物理连接进行关联。DemoManagedConnection也提供了产生虚拟连接实例的方法。DemoManagedConnection的代码如例程7所示。
例程7 DemoManagedConnection的代码
2 import javax.resource.*;
3 import javax.resource.spi.*;
4 import javax.security.auth.*;
5 import java.util.*;
6 import java.io.*;
7 import java.net.*;
8 import javax.transaction.xa.*;
9 //DemoManagedConnection代表了到EIS的物理的连接
10 public class DemoManagedConnection implements ManagedConnection
11 {
12 protected Socket socket;//和server连接的Socket
13 protected PrintStream serverStream;//
14 protected BufferedReader serverBufferedReader;
15 protected boolean destroyed;//是否销毁
16 protected PrintWriter out;
17 protected Set connections = new HashSet();//被管理的连接
18 protected Set connectionListeners = new HashSet();//连接监听器
19 DemoManagedConnectionFactory factory;//连接工厂
20
21 public DemoManagedConnection(DemoManagedConnectionFactory factory)
22 {
23 this.factory = factory;
24 }
25 //为连接增加事件监听器
26 public void addConnectionEventListener(ConnectionEventListener l)
27 {
28 connectionListeners.add(l);
29 }
30 //清除连接监听器
31 public void removeConnectionEventListener(ConnectionEventListener l)
32 {
33 connectionListeners.remove(l);
34 }
35
36 //返回连接工厂
37 public DemoManagedConnectionFactory getFactory ()
38 {
39 return factory;
40 }
41
42 //增加一个连接,并且返回它
43 public Object getConnection (Subject subject,
44 ConnectionRequestInfo cxRequestInfo)
45 {
46 DemoConnectionImpl connection = new DemoConnectionImpl();
47 connection.setManager(this);
48 connection.setLogWriter (out);
49 addConnection(connection);
50 return connection;
51 }
52
53 //清除占用的资源
54 public void cleanup() throws ResourceException
55 {
56 destroyedError();
57 Iterator it = connections.iterator();
58 while (it.hasNext())
59 {
60 DemoConnectionImpl demoConnectionImpl = (DemoConnectionImpl) it.next();
61 demoConnectionImpl.invalidate();
62 }
63 connections.clear();
64 }
65
66 //销毁所有的物理连接
67 public void destroy()
68 {
69 if (destroyed) return;
70 Iterator it = connections.iterator();
71 while (it.hasNext())
72 {
73 DemoConnectionImpl DemoConnectionImpl = (DemoConnectionImpl) it.next();
74 DemoConnectionImpl.invalidate();
75 }
76 connections.clear();
77 if (socket != null)
78 try {socket.close();}
79 catch (Exception e){}
80 destroyed = true;
81 }
82
83 //把一个Connection和这个被管理的连接关联
84 public void associateConnection(Object _connection)
85 throws ResourceException
86 {
87 destroyedError();
88 if (_connection instanceof DemoConnection)
89 {
90 DemoConnectionImpl connection =
91 (DemoConnectionImpl)_connection;
92
93 DemoManagedConnection demoManagedConnection = connection.getManager();
94 if (demoManagedConnection == this) return;
95 try
96 {
97 demoManagedConnection.removeConnection(connection);
98 }
99 catch(Exception e)
100 {
101 }
102 addConnection(connection);
103 connection.setManager (this);
104 }
105 else
106 {
107 throw new javax.resource.spi.IllegalStateException
108 ("Invalid connection object: " + _connection);
109 }
110 }
111 //不支持此方法
112 public XAResource getXAResource() throws ResourceException
113 {
114 throw new NotSupportedException("不支持分布式事务");
115 }
116
117 //不支持此方法
118 public LocalTransaction getLocalTransaction()
119 throws ResourceException
120 {
121 throw new NotSupportedException ("Local transaction not supported");
122 }
123
124 //返回元数据
125 public ManagedConnectionMetaData getMetaData()
126 {
127 return new DemoManagedConnectionMetaData(this);
128 }
129
130 protected void destroyedError()
131 throws javax.resource.spi.IllegalStateException
132 {
133 if (destroyed)
134 throw new javax.resource.spi.IllegalStateException
135 ("DemoManagedConnection 已经销毁");
136 }
137
138 //增加一个和此被管理连接(ManagedConnection)关联连接(Connection)
139 protected void addConnection(DemoConnection connection)
140 {
141 connections.add(connection);
142 }
143 //删除一个和此被管理连接(ManagedConnection)关联连接(Connection)
144 protected void removeConnection(DemoConnection connection)
145 {
146 connections.remove(connection);
147 }
148 //设置LogWriter
149 public void setLogWriter(PrintWriter _out)
150 {
151 out = _out;
152 }
153
154 public PrintWriter getLogWriter()
155 {
156 return out;
157 }
158 //判断是否已经销毁
159 public boolean isDestroyed()
160 {
161 return destroyed;
162 }
163 //关闭连接的事件,释放资源,由连接监听器来处理
164 void connectionClosedEvent()
165 {
166 Iterator it = connectionListeners.iterator();
167 while (it.hasNext())
168 {
169 ConnectionEventListener listener =
170 (ConnectionEventListener) it.next();
171 listener.connectionClosed
172 (new ConnectionEvent(this, ConnectionEvent.CONNECTION_CLOSED));
173 }
174 }
175
176 //打开物理连接,物理连接是和EIS的正在的连接。通过Socket来进行通信
177 public void openPhysicalConnection (String serverName, int portNumber)
178 throws UnknownHostException, IOException
179 {
180 socket = new Socket (serverName, portNumber);
181 serverStream = new PrintStream (socket.getOutputStream());
182 serverBufferedReader = new BufferedReader
183 (new InputStreamReader (socket.getInputStream()));
184 }
185 //业务方法,它是同步的,同时只能一个和Server进行通信
186 public synchronized String sayHello(String name)
187 throws ResourceException
188 {
189 serverStream.println (name);
190 try
191 {
192 String in = serverBufferedReader.readLine();
193 return in;
194 }
195 catch (Exception e)
196 {
197 throw new ResourceException
198 ("调用sayHello()发生错误: " + e.toString());
199 }
200 }
201 }
202
DemoManagedConnectionFactory
DemoManagedConnectionFactory是DemoManagedConnection的工厂,它的主要任务是创建和匹配DemoManagedConnection实例,在创建DemoManagedConnection实例时,DemoManagedConnection实例同时打开到EIS的物理连接。DemoManagedConnectionFactory的代码如例程8所示。
例程8 DemoManagedConnectionFactory的代码
在DemoManagedConnectionFactory类中,设置了两个属性,Port和Server,Port表示连接EIS使用的端口,Server表示连接EIS时使用的URL。这两个属性需要在资源适配器的部署描述符里指定具体的值。
2 import javax.resource.*;
3 import javax.resource.spi.*;
4 import javax.security.auth.*;
5 import java.util.Set;
6 import java.util.Iterator;
7 import java.io.*;
8 public class DemoManagedConnectionFactory
9 implements ManagedConnectionFactory, Serializable
10 {
11 protected PrintWriter out = new PrintWriter(System.out);
12 private int port;//连接EIS的端口
13 private String server;//eis服务器的url
14
15
16 //创建连接工厂,指定连接工厂的连接管理者为connectionManager
17 public Object createConnectionFactory
18 (ConnectionManager connectionManager)
19 {
20 DemoConnectionFactoryImpl demoConnectionFactoryImpl =
21 new DemoConnectionFactoryImpl (this, connectionManager);
22 demoConnectionFactoryImpl.setLogWriter(out);
23 return demoConnectionFactoryImpl;
24 }
25
26 //创建连接工厂,没有指定连接管理者
27 public Object createConnectionFactory()
28 {
29 DemoConnectionFactoryImpl demoConnectionFactoryImpl =
30 new DemoConnectionFactoryImpl (this, null);
31 demoConnectionFactoryImpl.setLogWriter(out);
32 return demoConnectionFactoryImpl;
33 }
34
35 //创建被管理的连接,被管理的连接是和EIS的真实连接,它是物理连接。
36 public ManagedConnection createManagedConnection(Subject subject, ConnectionRequestInfo cri)
37 throws ResourceException
38 {
39 DemoManagedConnection demoManagedConnection =
40 new DemoManagedConnection(this);
41 demoManagedConnection.setLogWriter(out);
42 try
43 {
44 //打开物理连接
45 System.out.println("打开物理连接.....");
46 demoManagedConnection.openPhysicalConnection (server, port);
47 return demoManagedConnection;
48 }
49 catch (IOException e)
50 {
51 throw new ResourceException (e.toString());
52 }
53 }
54
55 //匹配被管理的连接,如果匹配到连接,则返回,否则返回null
56 public ManagedConnection matchManagedConnections
57 (Set connections, Subject subject, ConnectionRequestInfo cri)
58 {
59 Iterator it = connections.iterator();
60 while (it.hasNext())
61 {
62 Object obj = it.next();
63 if (obj instanceof DemoManagedConnection)
64 {
65 DemoManagedConnection demoManagedConnection =
66 (DemoManagedConnection) obj;
67 DemoManagedConnectionFactory demoManagedConnectionf =
68 demoManagedConnection.getFactory();
69 if (demoManagedConnectionf.equals(this))
70 {
71 return demoManagedConnection;
72 }
73 }
74 }
75 return null;
76 }
77
78 public int hashCode()
79 {
80 if (server == null) return 0;
81 return server.hashCode();
82 }
83 //判断两个被管理的连接工厂是否相等
84 public boolean equals(Object o)
85 {
86 if (o == null) return false;
87 if (!(o instanceof DemoManagedConnectionFactory))
88 return false;
89 DemoManagedConnectionFactory other =
90 (DemoManagedConnectionFactory)o;
91 if (server.equalsIgnoreCase(other.server) &&
92 port == other.port) return true;
93 return false;
94 }
95 public void setLogWriter(java.io.PrintWriter out)
96 {
97 this.out = out;
98 }
99
100 public PrintWriter getLogWriter()
101 {
102 return out;
103 }
104
105 public void setServer (String server)
106 {
107 this.server = server;
108 }
109
110 public String getServer ()
111 {
112 return server;
113 }
114
115 public void setPort (Integer port)
116 {
117 this.port = port.intValue();
118 }
119
120 public Integer getPort ()
121 {
122 return new Integer(port);
123 }
124 }
125
编写部署描述符
下面的任务就是在部署描述符里指定资源适配器的相关接口和实现类。具体需要指定以下的接口和类:
ManagedConnectionFactory,这里是DemoManagedConnectionFactory;
Connectionfactory的接口,这里是javax..resource.cci.ConnectionFactory;
Connectionfactory的实现类,这里是DemoConnectionFactoryImpl;
连接的接口,这里是DemoConnection;
连接的实现类,这里是DemoConnectionImpl。
另外,还需要指定以下的属性:
是否支持事务,这里是NoTransaction;
安全认证的支持,这里是false;
DemoManagedConnectionFactory中使用的属性,其中Server的值为localhost,Port的值为2008。
例程9是资源适配器的具体内容,它要保存为ra.xml放在资源适配器打包文件RAR的META-INF目录下。
例程9 资源适配器的具体内容
2 <!DOCTYPE connector PUBLIC '-//Sun Microsystems, Inc.//DTD Connector 1.0//EN'
3 'http://java.sun.com/dtd/connector_1_0.dtd'>
4 <connector>
5 <display-name>DemoRA</display-name>
6 <vendor-name>HELLKING</vendor-name>
7 <spec-version>1.0</spec-version>
8 <eis-type>NO TRANS</eis-type>
9 <version>1.2</version>
10 <resourceadapter>
11 <managedconnectionfactory-class>com.hellking.jca.DemoManagedConnectionFactory
12 </managedconnectionfactory-class>
13 <connectionfactory-interface>javax.resource.cci.ConnectionFactory</connectionfactory-interface>
14 <connectionfactory-impl-class>com.hellking.jca.DemoConnectionFactoryImpl
15 </connectionfactory-impl-class>
16 <connection-interface>com.hellking.jca.DemoConnection</connection-interface>
17 <connection-impl-class>com.hellking.jca.DemoConnectionImpl</connection-impl-class>
18 <transaction-support>NoTransaction</transaction-support>
19 <config-property>
20 <config-property-name>Server</config-property-name>
21 <config-property-type>java.lang.String</config-property-type>
22 <config-property-value>localhost</config-property-value>
23 </config-property>
24 <config-property>
25 <config-property-name>Port</config-property-name>
26 <config-property-type>java.lang.Integer</config-property-type>
27 <config-property-value>2008</config-property-value>
28 </config-property>
29 <reauthentication-support>false</reauthentication-support>
30 </resourceadapter>
31 </connector>
32