Create forward-compatible beans in EJB, Part 1
Create forward-compatible beans in EJB, Part 2
I think your implementation of Portable_Context1_1.lookup() introduces an
unnecessary risk of a type mismatch error in the calling code. The code for
the Portable_Context1_0.lookup() ensures that the Object returned is an
instance of the type that has been passed in or an exception is thrown. The
1.1 version does not make this guarantee. I think an improvement would be
to add the lines
if (!(value.getClass() instanceof type)) {
throw new PortableConcextException()
}
right before the return statement in Portable_Context1_1.lookup(). By doing
this the 1.0 and 1.1 will both ensure that the type is correct before
returning.
Subject: Comments on Create forward-compatible beans in EJB article
Date: Thu, 16 Dec 1999 07:10:34 -0500
Richard,
I liked the above article alot. It certainly goes along way to making
life easier writing ejb's that support both 1.0 and 1.1.
Unfortunately I think I have found a flaw with the PortableContext1_0
class. If the ejb server that creates the EJBContext uses the load()
method in the Properties class then the name value pairs loaded will not
be correct. The load() method is documented as using ":" as a separator
character. Thus "java:comp/env/jdbc/x=x" will be loaded as Name=java
Value=comp/envjdbc/x=x.
The EJB Server that I am currently using to develop my beans is the
Jonas EJB server from bullsoft. This uses the load() method to build the
DeploymentDescriptor object and so I can use "java:comp/env/" as
prefixes for names.
Subject: Re: Comments on Create forward-compatible beans in EJB article
Date: Thu, 16 Dec 1999 07:00:30 -0600
From: Richard Monson-Haefel <[email protected]>
To: Richard Backhouse <[email protected]>
Richard,
Very interesting problem you have discovered. When I get time, (with your
permission) I will post your comments on my site with the recommendations
for improvements I have received from other. You have pointed out the
problem, what's your solution? I'm guessing that we would need to hide the
super context "java:comp/env/" in the concrete implementation and just use
the bean name (portableContext.lookup("AccountEJB")) from the bean.
Subject: Re: Comments on Create forward-compatible beans in EJB article
Date: Fri, 17 Dec 1999 08:22:27 -0500
Richard,
I tried this out last night and it seemed to work fine.
In the PortableContext1_1 class I just added the static string :
private static final String contextPrefix = "java:comp/env/";
and changed the jndi lookup to :
jndiContext = new InitialContext();
Object value = jndiContext.lookup(contextPrefix + name);
if(name.startsWith("jdbc")){
DataSource ds = (DataSource)value;
return ds.getConnection();
}
else if(name.startsWith("ejb")){
return PortableRemoteObject.narrow(value,type);
}
else
return value;
In the PortableContext1_0 class I just changed the startsWith() to look for "jdbc"
or "ejb".
Thus to load jdbc references I just prefix the name with "jdbc/" in the properties
file and for ejb references prefix with "ejb/"
public Object lookup(String name, Class type)throws PortableContextException{
int offset = name.indexOf(':');
name = name.substring(offset+1);
try{
Properties props = ejbContext.getEnvironment();
String value = props.getProperty(name);
if(value == null)
return null;
if(name.startsWith("comp/env/jdbc"))
return DriverManager.getConnection(value);
else if(name.startsWith("comp/env/ejb")){
InitialContext jndiContext = getInitialContext();
return jndiContext.lookup(value);
}else{
if(type == String.class)
return value;
else{
return primitiveWrapper(value, type);
}
}
}catch(Exception e){
throw new PortableContextException(e);
}
}
Subject: PortableContext
Date: Wed, 29 Mar 2000 22:59:31 +0200 (CEST)
From: Henrik Jonsson <[email protected]>
To: [email protected]
Thanks for the articles in JavaWorld concerning
PortableContext!
To be able to use bean environment variable names,
that begin with "jdbc" (ex. "jdbcArticle") and "ejb":
Exchange: aName.startsWith("comp/env/jdbc")
with: aName.startsWith("comp/env/jdbc/")
and
exchange: aName.startsWith("comp/env/ejb")
with: aName.startsWith("comp/env/ejb/")
Example:
A bean property containing the name of an article
"java:comp/env/jdbcArticle", is better to be able to
use than "java:comp/env/jdbc/Article", which implies
that Article is some sort of connection property.
Using the bean property "java:comp/env/jdbcArticle",
without the modification suggested above, will lead to
that a "DriverNotFoundException" is thrown, as
aName.startsWith("comp/env/jdbc") returns true for the
property string.
Best regards,
Henrik E. Jonsson
Dear Richard!
This is Jordi Paris from Andersen Consulting, Barcelona.
First of all, we want to congratulate you for your article in Javaworld about
writing forward-compatible EJB.
Since your article, we are developing compatible EJB (across EJB versions and
across EJB containers vendors).
Congratulations!!!
About the article, we have a little doubt. In part 2, you say that we can choose
between several PortableContext implementations at deploying time only changing
the system property "java.ejb.portable_context".
Our questions are:
* How can we change this system property ("java.ejb.portable_context")?
* If not, can we create "our" particular property (for example,
"com.ac.gaudi.portable_context")?
* Is there any standard way in all EJB containers to add the
"com.ac.gaudi.portable_context" as a system property? Can we use a .property
file? How?
* If there is no standard way in the EJB containers of adding a system property,
can we assume that all EJB containers will support adding system properties? (of
course, assuming that each EJB containers will have a container specific way of
adding system properties).
We will appreciate very much your help.
Thank you very much in advance,
Jordi Paris
Subject: Re: "java.ejb.portable_context" system property
Date: Mon, 10 Apr 2000 09:00:52 -0500
From: Richard Monson-Haefel <[email protected]>
To: [email protected]
Hi Jordi,
You have asked a very good question to which I have a somewhat fuzzy answer.
Every EJB server should provide a mechanism for introducing new System properties at
the time the server is started. For example, Weblogic, allows you to add system
properties using the standard java -D switch
(http://www.weblogic.com/docs51/admindocs/properties.html#multiple).
All JVMs should support a -D switch that allows you add system properties, so for
example you could run a program with the following command line and it will add the
system property "java.ejb.portable_context" with the value you specify.
java -Djava.ejb.portable_context=com.ac.gaudi.portable_context MyServer
You can add as many new system properties as you like by separating them with spaces
and prepending each with -D as shown below
java -Dprop_1=value1 -Dprop_2=value2 -Dprop_3=value3 MyClass
Unfortunately, each server will support this feature in their own way and its not
immediately clear how to do this when running a server as a NT Service -- If you
find out let me know.
I hope this helps!
Richard