Tryin to develop a jca connector

C

Cacho

Hi

I'´ve a package that allow applications connect to an IBM host using
sockets and 3270 telnet protocol.

I want to isolate and standarize such layer using JCA to run it as a
resource adapter in an application server.

I'm new to jca and reading specification is drivin me a little bit
confused. I' ve "googled" for sample code but the few I found are
simple db resource adapters implementations so I wonder if some one
could point me to a non db jca samples... or guides/books about this
matter.

I've found this sample code:

http://java.sun.com/developer/technicalArticles/J2EE/connectorclient/resourceadapter.html

but the article is similar to those I've read but I'm still confused.

I know I need to wrap my EIS connector with my resource adapter but
what I couldn´t see clear is where should I do it.

I supposed that it should be in the lower layer, the connection
implementation, but all the sample codes I saw make and instance of
this class but recommend to put the EIS code in the managedconnection
class.

I've a simple class called CICSSocket that make the connection with
EIS and with two methods read and write to allow those operation the
EIS throw sockets and a open method to open the socket.

If make an instance of CICSSocket in the Connection class constructor,
it will be a wrapper but I'll be returning a Connection instance, not
a CICSSocket instance, so how the AS or the client will call
CICSSockets methods ? How the AS could pass parameters to CICSSocket
to make the connection ?

What happen if I do the above in the ManagedConnection class as I saw
in various samples ? How will it work to wrap my class ?

So, I've a clear map of all but I really don't understand how all
components interact and how to do it and couldn´t found real samples
about it.

Could somebody please send me a simple sample code or explanation to
make me see the light ?

Thanks in advance

C
 
L

Lee Fesperman

Cacho said:
I'´ve a package that allow applications connect to an IBM host using
sockets and 3270 telnet protocol.

I want to isolate and standarize such layer using JCA to run it as a
resource adapter in an application server.

...

I know I need to wrap my EIS connector with my resource adapter but
what I couldn´t see clear is where should I do it.

I supposed that it should be in the lower layer, the connection
implementation, but all the sample codes I saw make and instance of
this class but recommend to put the EIS code in the managedconnection
class.

I've a simple class called CICSSocket that make the connection with
EIS and with two methods read and write to allow those operation the
EIS throw sockets and a open method to open the socket.

If make an instance of CICSSocket in the Connection class constructor,
it will be a wrapper but I'll be returning a Connection instance, not
a CICSSocket instance, so how the AS or the client will call
CICSSockets methods ? How the AS could pass parameters to CICSSocket
to make the connection ?

What happen if I do the above in the ManagedConnection class as I saw
in various samples ? How will it work to wrap my class ?

So, I've a clear map of all but I really don't understand how all
components interact and how to do it and couldn´t found real samples
about it.

What you're missing here is the JCA (Client) Connection class can be
any class. JCA has no requirements for this class. Probably, you
should use the CICSSocket wrapper as your Connection class.

Your ManagedConnectionFactory class could then construct an instance
of the CICSSocket wrapper and open the socket in its
createManagedConnection() method, using parameters from your (Client)
Connection Factory. The Connection Factory has parameters set as a
JavaBean.

The App Server (AS) doesn't call methods in the (Client) Connection
instance; it doesn't even see it. The client application retrieves the
Connection instance with a specific method in the (Client) Connection
Factory. The client normally retrieves the Connection Factory instance
through JNDI and then casts it to the specific Connection Factory
class (for your Resource Adapter).

See my article in JDJ Online -- "Understanding JCA" (http://sys-
con.com/story/?storyid=46283&de=1). It initially discusses JDBC but
does provide a blueprint for a general Resource Adapter. There is not
much code, but it does show the code for how a client application
retrieves a Client Connection instance (of any type) through JNDI.
 
C

Cacho

What you're missing here is the JCA (Client) Connection class can be
any class. JCA has no requirements for this class. Probably, you
should use the CICSSocket wrapper as your Connection class.

Your ManagedConnectionFactory class could then construct an instance
of the CICSSocket wrapper and open the socket in its
createManagedConnection() method, using parameters from your (Client)
Connection Factory. The Connection Factory has parameters set as a
JavaBean.

The App Server (AS) doesn't call methods in the (Client) Connection
instance; it doesn't even see it. The client application retrieves the
Connection instance with a specific method in the (Client) Connection
Factory. The client normally retrieves the Connection Factory instance
through JNDI and then casts it to the specific Connection Factory
class (for your Resource Adapter).

See my article in JDJ Online -- "Understanding JCA" (http://sys-
con.com/story/?storyid=46283&de=1). It initially discusses JDBC but
does provide a blueprint for a general Resource Adapter. There is not
much code, but it does show the code for how a client application
retrieves a Client Connection instance (of any type) through JNDI.


Hi

Well, I did my resource adaptar defined as follows:

--------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE connector PUBLIC '-//Sun Microsystems, Inc.//DTD Connector
1.0//EN' 'http://java.sun.com/dtd/connector_1_0.dtd'>

<connector>
<display-name>CometResourceAdapter</display-name>
<vendor-name>BancSabadell</vendor-name>
<spec-version>1.5</spec-version>
<eis-type>CicsSocket</eis-type>
<version>1.0</version>
<resourceadapter>
<managedconnectionfactory-
class>com.bs.cds.jca.CdsManagedConnectionFactoryImpl</
managedconnectionfactory-class>
<connectionfactory-interface>javax.resource.cci.ConnectionFactory</
connectionfactory-interface>
<connectionfactory-impl-
class>com.bs.cds.jca.CdsConnectionFactoryImpl</connectionfactory-impl-
class>
<connection-interface>javax.resource.cci.Connection</connection-
interface>
<connection-impl-class>com.bs.cds.jca.CdsConnection</connection-impl-
class>
<transaction-support>NoTransaction</transaction-support>
</resourceadapter>
</connector>
----------------------------------

But when I deployed in my JBoss I receive the error:


-------------------------
org.jboss.deployment.DeploymentException: Error parsing meta data
jar:file:/D:/j
boss/server/jcara/tmp/deploy/tmp34080com.bs.cds.jca.ra-0.0.1.rar!/META-
INF/ra.xm
l; - nested throwable: (org.jboss.xb.binding.JBossXBException: Failed
to parse s
ource.)
at
org.jboss.deployment.DeploymentException.rethrowAsDeploymentException
(DeploymentException.java:39)
at
org.jboss.deployment.ObjectModelFactorySimpleSubDeployerSupport.parse
MetaData(ObjectModelFactorySimpleSubDeployerSupport.java:41)
at
org.jboss.deployment.SimpleSubDeployerSupport.init(SimpleSubDeployerS
upport.java:73)
at org.jboss.deployment.MainDeployer.init(MainDeployer.java:
843)
at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:
780)
at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:
753)
at sun.reflect.GeneratedMethodAccessor49.invoke(Unknown
Source)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatch
er.java:141)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:80)
at
org.jboss.mx.interceptor.AbstractInterceptor.invoke(AbstractIntercept
or.java:118)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:74)
at
org.jboss.mx.interceptor.ModelMBeanOperationInterceptor.invoke(ModelM
BeanOperationInterceptor.java:127)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:74)
at
org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.
java:245)
at
org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:644)
at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:
176)
at $Proxy9.deploy(Unknown Source)
at
org.jboss.deployment.scanner.URLDeploymentScanner.deploy(URLDeploymen
tScanner.java:319)
at
org.jboss.deployment.scanner.URLDeploymentScanner.scan(URLDeploymentS
canner.java:507)
at org.jboss.deployment.scanner.AbstractDeploymentScanner
$ScannerThread.
doScan(AbstractDeploymentScanner.java:192)
at
org.jboss.deployment.scanner.AbstractDeploymentScanner.startService(A
bstractDeploymentScanner.java:265)
at
org.jboss.system.ServiceMBeanSupport.jbossInternalStart(ServiceMBeanS
upport.java:274)
at
org.jboss.system.ServiceMBeanSupport.jbossInternalLifecycle(ServiceMB
eanSupport.java:230)
at sun.reflect.GeneratedMethodAccessor2.invoke(Unknown Source)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatch
er.java:141)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:80)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:72)
at
org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.
java:245)
at
org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:644)
at org.jboss.system.ServiceController
$ServiceProxy.invoke(ServiceControl
ler.java:943)
at $Proxy0.start(Unknown Source)
at
org.jboss.system.ServiceController.start(ServiceController.java:428)
at sun.reflect.GeneratedMethodAccessor9.invoke(Unknown Source)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatch
er.java:141)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:80)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:72)
at
org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.
java:245)
at
org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:644)
at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:
176)
at $Proxy4.start(Unknown Source)
at org.jboss.deployment.SARDeployer.start(SARDeployer.java:
285)
at org.jboss.deployment.MainDeployer.start(MainDeployer.java:
989)
at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:
790)
at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:
753)
at org.jboss.deployment.MainDeployer.deploy(MainDeployer.java:
737)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
org.jboss.mx.interceptor.ReflectedDispatcher.invoke(ReflectedDispatch
er.java:141)
at org.jboss.mx.server.Invocation.dispatch(Invocation.java:80)
at
org.jboss.mx.interceptor.AbstractInterceptor.invoke(AbstractIntercept
or.java:118)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:74)
at
org.jboss.mx.interceptor.ModelMBeanOperationInterceptor.invoke(ModelM
BeanOperationInterceptor.java:127)
at org.jboss.mx.server.Invocation.invoke(Invocation.java:74)
at
org.jboss.mx.server.AbstractMBeanInvoker.invoke(AbstractMBeanInvoker.
java:245)
at
org.jboss.mx.server.MBeanServerImpl.invoke(MBeanServerImpl.java:644)
at org.jboss.mx.util.MBeanProxyExt.invoke(MBeanProxyExt.java:
176)
at $Proxy5.deploy(Unknown Source)
at org.jboss.system.server.ServerImpl.doStart(ServerImpl.java:
453)
at org.jboss.system.server.ServerImpl.start(ServerImpl.java:
330)
at org.jboss.Main.boot(Main.java:187)
at org.jboss.Main$1.run(Main.java:438)
at java.lang.Thread.run(Thread.java:619)
Caused by: org.jboss.xb.binding.JBossXBException: Failed to parse
source.
at
org.jboss.xb.binding.parser.sax.SaxJBossXBParser.parse(SaxJBossXBPars
er.java:125)
at
org.jboss.xb.binding.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java
:150)
at
org.jboss.deployment.ObjectModelFactorySimpleSubDeployerSupport.parse
MetaData(ObjectModelFactorySimpleSubDeployerSupport.java:37)
... 68 more
Caused by: java.lang.IllegalArgumentException: Unknown connector
newChild: nuri=
localName=managedconnectionfactory-class
attrs=org.apache.xerces.parsers.Abstra
ctSAXParser$AttributesProxy@cc9d70
at
org.jboss.resource.deployment.ResourceAdapterObjectModelFactory.newCh
ild(ResourceAdapterObjectModelFactory.java:162)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at
org.jboss.xb.binding.ObjectModelBuilder.invokeFactory(ObjectModelBuil
der.java:421)
at
org.jboss.xb.binding.DelegatingObjectModelFactory.newChild(Delegating
ObjectModelFactory.java:78)
at
org.jboss.xb.binding.ObjectModelBuilder.startElement(ObjectModelBuild
er.java:323)
at org.jboss.xb.binding.parser.sax.SaxJBossXBParser
$DelegatingContentHan
dler.startElement(SaxJBossXBParser.java:217)
at
org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Sour
ce)
at
org.apache.xerces.impl.dtd.XMLDTDValidator.startElement(Unknown Sourc
e)
at
org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unkn
own Source)
at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl
$FragmentContent
Dispatcher.dispatch(Unknown Source)
at
org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Un
known Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown
Source)
at org.apache.xerces.parsers.XML11Configuration.parse(Unknown
Source)
at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown
Source)
at org.apache.xerces.jaxp.SAXParserImpl
$JAXPSAXParser.parse(Unknown Sour
ce)
at
org.jboss.xb.binding.parser.sax.SaxJBossXBParser.parse(SaxJBossXBPars
er.java:121)
... 70 more
-------------------------


I wonder if someone could give me a clue about the origin of the
problem. I think my ra.xml is well defined and my
managedconnectionfactory-class too.

Thanks in advance

J
 
L

Lee Fesperman

Cacho said:
Well, I did my resource adaptar defined as follows:

--------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE connector PUBLIC '-//Sun Microsystems, Inc.//DTD Connector
1.0//EN' 'http://java.sun.com/dtd/connector_1_0.dtd'>

<connector>
<display-name>CometResourceAdapter</display-name>
<vendor-name>BancSabadell</vendor-name>
<spec-version>1.5</spec-version>
<eis-type>CicsSocket</eis-type>
<version>1.0</version>
<resourceadapter>
<managedconnectionfactory-
class>com.bs.cds.jca.CdsManagedConnectionFactoryImpl</
managedconnectionfactory-class>
<connectionfactory-interface>javax.resource.cci.ConnectionFactory</
connectionfactory-interface>
<connectionfactory-impl-
class>com.bs.cds.jca.CdsConnectionFactoryImpl</connectionfactory-impl-
class>
<connection-interface>javax.resource.cci.Connection</connection-
interface>
<connection-impl-class>com.bs.cds.jca.CdsConnection</connection-impl-
class>
<transaction-support>NoTransaction</transaction-support>
</resourceadapter>
</connector>
----------------------------------

But when I deployed in my JBoss I receive the error:


-------------------------
org.jboss.deployment.DeploymentException: Error parsing meta data
jar:file:/D:/j
boss/server/jcara/tmp/deploy/tmp34080com.bs.cds.jca.ra-0.0.1.rar!/META-
INF/ra.xm
l; - nested throwable: (org.jboss.xb.binding.JBossXBException: Failed
to parse s
ource.)
at
...
at
org.apache.xerces.impl.dtd.XMLDTDValidator.startElement(Unknown Sourc
e)
-------------------------

I wonder if someone could give me a clue about the origin of the
problem. I think my ra.xml is well defined and my
managedconnectionfactory-class too.

Your ra.xml is well formed for JCA 1.0 except you specified <spec-
version> as '1.5'. I assume it's failing the XML DTD Validator for
that reason. You should have used <spec-version>1.0</spec-version>.
Note: JCA 1.5 changes the format of ra.xml.
 
C

Cacho

Your ra.xml is well formed forJCA1.0 except you specified <spec-
version> as '1.5'. I assume it's failing the XML DTD Validator for
that reason. You should have used <spec-version>1.0</spec-version>.
Note:JCA1.5 changes the format of ra.xml.


Hi

I've solved the problem but have some doubts.

1 - How could I pass parameters to my jca ? You told me about bean
properties in ManagedConnectionFactory, but how should I set that in
ra.xml ? And more, how could I set them outside the ra.xml ?


2 - My connection use some typical parameters: host, port, etc that
could be set inside ra.xml, but I need to set a variable one for each
connection. Which could be the best way to do it ?

Thanks in advance

J
 
L

Lee Fesperman

Cacho said:
I've solved the problem but have some doubts.

Please tell us your solution so others can learn.
1 - How could I pass parameters to my jca ? You told me about bean
properties in ManagedConnectionFactory, but how should I set that in
ra.xml ? And more, how could I set them outside the ra.xml ?

2 - My connection use some typical parameters: host, port, etc that
could be set inside ra.xml, but I need to set a variable one for each
connection. Which could be the best way to do it ?

You probably should declare your parameters in ra.xml using <config-
property>, but setting values other than defaults here will make them
hard to change. ra.xml is normally packed inside a rar file, and you
will have to redeploy it.

The usual way is to specify your properties for your client connection
factory. When you make a JNDI entry for your client connection
factory, your app server should allow you to specify JavaBean
properties for it.

Alternatively, you can set properties for the client connection
factory in your code after you retrieve your client connection factory
from JNDI.
 
C

Cacho

Please tell us your solution so others can learn.


I've just changed my xml to 1.0 version. :)


Now I've some doubts about how my connector is working so I need to
ask something.

If I define, in my AS, a min pool of 10 and a max pool of 30
connections, how is supposed to work ? Should my AS create 10
connections by default at start up ? Should it just create a
ManagedConnectionFactory and will create connections as they be asked
by clients till get the max pool count ?

I need to be sure about how it works to know if I my ra is working
right or wrong...

Thanks in advance

C
 
L

Lee Fesperman

Cacho said:
I've just changed my xml to 1.0 version. :)

Thanks for the update.
Now I've some doubts about how my connector is working so I need to
ask something.

If I define, in my AS, a min pool of 10 and a max pool of 30
connections, how is supposed to work ? Should my AS create 10
connections by default at start up ? Should it just create a
ManagedConnectionFactory and will create connections as they be asked
by clients till get the max pool count ?

I would expect it wouldn't open live connections at startup. In fact,
I suspect that it wouldn't even instantiate the Managed Connection
Factory until driven by user request. It would use the min pool value
as a lower boundary that the size of the pool couldn't fall below once
it reached the min. The pool would contain Managed Connection
instances.
I need to be sure about how it works to know if I my ra is working
right or wrong...

This depends on the implementation of the Container Software, such as
an App Server (AS). I doubt they will document their internal
algorithm ... unless it is open source. So, I'd suggest you instrument
your code to trace calls to various entry points in your Resource
Adapter (RS).
 
C

Cacho

This depends on the implementation of the Container Software, such as
an App Server (AS). I doubt they will document their internal
algorithm ... unless it is open source. So, I'd suggest you instrument
your code to trace calls to various entry points in your Resource
Adapter (RS).


Hi

Thanks for your reply.

I've checked that my JBoss starts all the connection I configured in
the xml file but I people from JBoss team told me that´s configurable.

I've tested my connector and is working well except when I try to make
a matchManaged connections. Till now it was returning null but today
I've tried to do it well but... I've been looking sample codes on the
net and found that there check for some properties like user
credentials to match connections.

As my adapter doesn´t use credentials I don´t figure out what to do
and so far, I don´t figure out which objetcs are trying to be matched.
As I've read, the application server will give to my
matchManagedconnection with a set of candidate connections but, they
should be match against what ?

Could you please clarify that matter ?

Thanks in advance

C
 
L

Lee Fesperman

Cacho said:
I've tested my connector and is working well except when I try to make
a matchManaged connections. Till now it was returning null but today
I've tried to do it well but... I've been looking sample codes on the
net and found that there check for some properties like user
credentials to match connections.

As my adapter doesn´t use credentials I don´t figure out what to do
and so far, I don´t figure out which objetcs are trying to be matched.
As I've read, the application server will give to my
matchManagedconnection with a set of candidate connections but, they
should be match against what ?

Could you please clarify that matter ?

The container software (AS) would use matchManagedConnection() to
check if a new connection is in its pool of available connections
(ManagedConnection). The first argument is a Set containing available
connections from the pool. The third argument (ConnectionRequestInfo)
contains the properties for the new connection. You said you had
connection properties, right? You should look in the set for a
ManagedConnection object whose connection properties match those in
the new connection ... and return it if it does (I'd also check that
the ManagedConnection from the set is one of yours.)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,780
Messages
2,569,611
Members
45,273
Latest member
DamonShoem

Latest Threads

Top