Technical FAQ:Questions about WebLogic EJB
FAQ Index
SQL Exception and JTS JDBC driver
The following SQLException was thrown from my JDBC code:
"The coordinator has rolled back the transaction.
No further JDBC access is allowed within this transaction."
What's going on?
This exception, which is thrown by the
WebLogic JTS JDBC driver, means that the transaction in which the JDBC
Connection was participating was rolled back at some point prior to or
during the JDBC call. The rollback may have happened in an earlier EJB
invoke that was part of the transaction or the rollback may have
occurred because the transaction timed out. In either case, the
transaction will be rolled back, the connection returned to the pool
and the database resources released. In order to proceed, the JTS
JDBC Connection must be closed and reopened in a new transaction.
Using EJBeans with the JDBC-ODBC bridge and Microsoft Access
I'm having trouble accessing a Microsoft Access database using EJB and
the JDBC-ODBC bridge. What's going on?
The Microsoft Access database does not support the type of transaction
processing required for use with EJB and the JDBC-ODBC bridge. We
recommend that you use another, more robust database such as
Microsoft's SQL Server, Informix, Sybase, or Oracle.
Speeding up compilation of EJBeans
How can I make my EJBeans compile faster?
By default, ejbc uses javac as a compiler. For faster
performance, specify a different compiler (such as Symantec's sj) using the
-compiler flag. Note that when you use the -compiler flag, you must set both
the -classpath and -d flags.
EJBC compiler and the manifest file
I have created my manifest file, placed it in the deployment
directory, and made sure that my CLASSPATH is set correctly. However,
when I try to run the EJBC compiler, I receive an error message
stating that the EJBeans have not been built correctly. Why is the
compiler unable to locate my manifest file?
The EJBC compiler requires that the manifest file permissions be
read-write-execute (rwx or 755). If you change the permissions ($ chmod manifest 755) to
rwx, your EJBeans should compile correctly.
Custom finder methods for container-managed beans
How can I implement my own custom finder methods for a
container-managed bean?
Bean-provided finder methods are not allowed under the EJB spec
(section 9.10.6). To implement your own finder, you have to use
bean-managed persistence.
WebLogic supports an extensive list of container-generated finder
methods, which are documented in the WebLogic Developer Guide, Using WebLogic Enterprise
JavaBeans and in the Deployment document, Using the WebLogic EJB
Deployment Wizard.
Rollback exceptions with EJB applications
When my EJB application produces a rollback exception, the
application seems to come to a complete halt. Is there something I
can do to optimize how these exceptions are handled?
This problem has been observed when running Windows NT and Oracle and
may be due to the way that NT prioritizes threads
. The problem is currently under investigation by
WebLogic. You may be able to improve performance of your application
by decreasing the number of execute threads and increasing the number
of connections in the connection
pools. For database intensive applications, this is generally a
good idea anyway, because the extra threads will waste time waiting
for a database connection to become available. Remember that you
should set the number of execute threads at least one higher than the
number of connections in the connection pool.
Handling exceptions with WebLogic EJB from a Visual Basic client
We are using WebLogic COM from a Visual Basic client to access EJBeans
that are deployed under WebLogic. If a bean method throws an
exception, is it possible to get the exception object, invoke a method
on it and then determine if the error generated by Visual Basic is a
ValidationException or a RemoteException?
Unfortunately, there are many things you can't do in Visual Basic that
you can do in Java. When using Visual Basic, you are limited to looking
up RMI
and EJB objects and calling methods on those objects.
The best way to handle exceptions is to catch them in the
EJBean and return an error message or code to the Visual Basic client.
Using a database for EJB bean-managed persistence
I am using bean-managed persistence. Does my persistence mechanism
need to use the WebLogic JTS driver?
Yes, you must use the WebLogic JTS
pool driver for bean-managed EJB persistence. Please see EJB and JDBC for
instructions. You must set up a connection pool for use with
EJB, and you must access that pool only with the JTS pool
driver. WebLogic has successfully tested EJB persistence with both the
jdbcKona/Oracle driver and Cloudscape.
Bugs in Microsoft SDK for Java that affect EJB users
In late June 1998, WebLogic discovered (and reported to Microsoft) a
Microsoft SDK for Java bug that affects EJB users. Microsoft SDK for
Java serializes
objects in a manner that is different from what other JVMs
expect, and which causes serialization problems when using EJBeans. It
means that you must use Microsoft SDK For Java instead of Java when running any EJB
utilities such as DDCreator or the EJB compiler (ejbc) if you intend to
run WebLogic under Microsoft SDK For Java and use EJBeans. See the EJB examples for a
build script (buildms.bat) that demonstrates this.
Limits on trying out EJB?
I downloaded WebLogic 3.0.3, the version that has EJB, to experiment a
little with EJB. When I bring up a lot of clients using the same bean,
my program eventually stops working. What's the problem?
WebLogic EJB
in version 3.0.3 is based on the 0.8 Enterprise JavaBean
specification. In version 3.0.3, WebLogic released an early
availability version of Enterprise JavaBeans -- before the
specification was considered fully ready -- to give our customers some
experience with the API. There are some problems in concurrency
control, which is based on a transitional version of JTS (Java
Transaction Services)
expect, and which causes serialization problems when
using EJBeans. It means that you must use Microsoft SDK for Java
instead of Java when running any EJB utilities such as DDCreator or the
EJB compiler (ejbc) if you intend to run WebLogic under Microsoft SDK
for Java and use EJBeans. See the EJB examples for a build script
(buildms.bat) that demonstrates this.
EJB compatibility
When writing my EJBeans, is there anything that I should keep in mind
to make my beans portable and compatible with EJB servers today and in
the future?
If you add code that imports WebLogic-specific classes, such as
weblogic.security.acl.Security,
then you will have made your bean specific to WebLogic.
This may be a problem if you are building a bean for third-party use
that needs to run in any EJB-compliant server.
The following note from Sun describes three methods
that will be changed in a future release of EJB.
Note on EJB forward compatibility
This note identifies three methods in the EJB 1.0 API
that will be subject to changes in a future release of EJB. We
describe the reasons for changing these methods, and suggest the steps
that the application vendors and EJB server/container vendors should
take to minimize impact of the changes.
1. What are the methods that will change in future EJB specification
The EJB specification depends on other Java APIs. Due to the changes
to the other Java APIs, three methods of the javax.ejb.EJBContext
interface will be removed or replaced in a future EJB release.
The affected methods are these three methods of the interface
javax.ejb.EJBContext:
- Identity getCallerIdentity();
- boolean isCallerInRole(Identity role);
- UserTransaction getUserTransaction()
throws IllegalStateException;
2. Why these methods will be changed in a future release
There have been a number of improvements in the JDK
security which will be introduced in JDK 1.2. One of the changes is
the deprecation of the class
java.security.Identity. Although EJB 1.0 does not require
JDK 1.2, we believe that it would be better if EJB would not
proliferate the use of a deprecated class.
The use of the class
java.security.Identity will be replaced by using the
interface java.security.Principal. The
method getUserTransaction will be
affected because of the rename of the
javax.jts package to
javax.transaction. This rename was necessary to clearly
separate the Java Transaction Service (JTS)
extension from the user-level transaction demarcation interface
UserTransaction. EJB depends on the interface UserTransaction, but not
on JTS, and the prefix javax.jts was
confusing to many people. Other APIs such as JDBC
and JMS depends already on the new name and we didn't want to force
vendors to support two packages with different names but identical
functionality.
3. What should enterprise bean vendors do before
the EJB spec changes
become available
Application vendors who want to ensure that their enterprise beans will
work with a future release of EJB should avoid using these three methods
in the enterprise bean code.
We believe that most enterprise beans will not be affected by this change
because most beans should rely on their deployment descriptor to control
transactions and security.
4. What should EJB server/container vendors do before the EJB spec changes
become available
EJB server vendors have two choices with respect to this upcoming change:
(a) Do not support these methods in their products. The implementation
of the method might, for example, throw an exception.
(b) Support these methods in their current products, and deprecate
them when migrating their products to a future EJB release.
WebLogic is following option (b): it currently supports these methods,
and will deprecate them in a future release of EJB.
WebLogic EJB and CORBA
I'd like to use the WebLogic EJB service and plug it into my
CORBA-based
architecture. I can make my ORB
work with JavaBlend. But how does WebLogic EJB fit into the picture?
Currently you cannot export a WebLogic EJBean to CORBA directly. We
are looking at adding this in the future. For now, you can gateway to
your EJBeans via the WebLogic Remote
and WebLogic Events
services which are directly exportable to CORBA.
We agree on the importance of object-relational mapping. Stay tuned.
Exceptions loading EJBeans under Microsoft SDK for Java
Why is my WebLogic Server running under Microsoft SDK for Java throwing an exception
when it loads my EJBeans?
There is an incompatibility in the way in which JavaSoft SDK and Microsoft SDK for Java
serialize
objects, in this case with
javax.ejb.deployment.SerializableField.
We have logged an issue with Microsoft, but until it is fixed, you need
to "create" your EJBeans (such as the EJB examples) using jview.exe instead of Sun's java.exe.
Here is how to do this for the examples shipped with WebLogic:
- Make sure that your environment has the CLASSPATH
properly set to include jview
- Modify the build.bat script,
replacing java
with jview
(buildms.bat has this already done)
- Build the examples as described in the example's documentation
- Deploy the EJBeans in WebLogic and start the server
We have received verification that the bug (the removal of a class
initializer resulted in a different serialization ID) has been fixed
in the final SDK 3.0 VM.
Polymorphic responses from create() and find() methods
Why is there no polymorphic-type response from a create() or find() method?
Section 9.7.8 of the EJB 1.0 spec reads:
'The return type for a create method must be the enterprise
Bean's remote interface type.'
Further on, it reads:
'The return type for a finder method must be the enterprise Bean's
remote interface type, or a collection thereof.'
The weblogic.ejbc compiler strictly checks this and prohibits any
polymorphic type of response from a create or find method.
I'd like a method in the base class for a home interface such as:
public BaseEntityBean findByPrimaryKey(BasePK key);
I'd like to polymorphically call any valid methods on
BaseEntityBean. But since I can't do this, I'm forced to use reflection to invoke the method I want.
The reason the
create() and
find() methods are not polymorphic
is much the same reason constructors are not
polymorphic in Java.
The derived classes generally do
not know or cannot initialize the base class
properly.
In the case of the finders, the same argument cannot be made. We have
in the past loosened restrictions that JavaSoft has made when it was
determined that our customers' benefit would outweigh any objections.
The issue here is portability: someone may do something that they
didn't realize was actually against the specification and think that
they can take their EJBean to another EJB server without a problem.
Using ejbActivate() and ejbPassivate()
When are ejbActivate() and
ejbPassivate() called?
For entity beans, when the EJBean goes from the pooled to the ready
state, ejbActivate() is called. When
it goes from the ready to the pooled state,
ejbPassivate() is called.
For stateful session beans,
ejbPassivate() is called when the cache is full and the
EJBean is sent to the backing store, and
ejbActivate() is called when the bean returns from the
backing store.
For stateless session beans, these methods are never called.
Referencing an EJBean from within an EJBean
How do I reference one EJBean from within another EJBean?
Example:
myABean and
myBBean are two EJBeans:
public class myABean implements EntityBean {...}
public class myBBean implements EntityBean {...}
myABean's interface is
myAInterface;
myBBean's interface is
myBInterface:
public interface myAInterface extends EJBObject, Remote {...}
public interface myBInterface extends EJBObject, Remote {...}
To reference a myBBean from
within myABean,
reference myBBean directly:
public class myABean implements EntityBean {
...
myBInterface b;
...
}
However, you must make sure that myABean's member variable
'b' cannot instantiate and hold an instance of a myBBean. Instead,
myABean must do a JNDI
lookup of
myBBean's home, and then
myBBeanHome bHome = // JNDI lookup
myBInterface b = bHome.find();
b = bHome.create();
To make the myBBean persistent, store the
primary key, and then with load(),
restore and findByPrimaryKey() the
entity bean. An example using a similar technique for non-primitive
attributes is shown in a previous
question.
Re-entrant EJbeans
Why are re-entrant EJBeans dangerous?
According to section 9.6 of the EJB 1.0
specification, it is best to avoid re-entrant calls for entity
beans. A re-entrant call is when a method of bean A calls a method of
bean B which in turn calls a method of bean A.
Such a scenario is considered dangerous because it could lead to a
deadlock. WebLogic EJB supports re-entrant calls; however, it is the
bean developer's responsibility to avoid any "dangerous" situations.
EJB transactions and multiple databases
Can EJB handle transactions across multiple databases?
Currently, the transaction manager in EJB does not have logging, which
is a requirement for handling transactions across multiple databases.
Though it might seem possible to accomplish this with multiple entity
EJBeans handling transactions to each database and a single session
EJBean to manage a transaction with the entity EJBeans, if any one
transaction fails, it is not possible to roll the other transactions
back.
Using a database for transactions with entity beans
How do I use a database for transactions with entity beans?
There are two approaches: container-managed persistence, or
bean-managed persistence. Each approach is shown in an example included
in the WebLogic distribution.
In both cases, you should use a connection pool specifically for
EJB.
With container-managed persistence, you specify the connection pool
for your database connectivity, and persistence and transactions will
be handled automatically by EJB.
With bean-managed persistence, you can specify the connection pool for
your database connectivity, but you will be specifying the persistence
and transactions yourself.
Using TX_SUPPORTS
How do I use TX_SUPPORTS?
When I run the deployment descriptor file through DDCreator, it throws the following
exception:
Exception in file UserInfoDD.txt:
java.lang.IllegalArgumentException:
Illegal value of transactionAttribute
at javax.ejb.deployment.ControlDescriptor.
setTransactionAttribute(ControlDescriptor.java:275)
at weblogic.ejb.utils.DDCreator.createControlDescriptor
(DDCreator.java:627)
at weblogic.ejb.utils.DDCreator.createControlDescriptors
(DDCreator.java:574)
at weblogic.ejb.utils.DDCreator.createDescriptor
(DDCreator.java:320)
at weblogic.ejb.utils.DDCreator.createDescriptor
(DDCreator.java:88)
at weblogic.ejb.utils.DDCreator.main(DDCreator.java:41)
This is a bug in javax.ejb.deployment.ControlDescriptor.
The class defines
TX_SUPPORTS. However, when the value is passed to
setTransactionAttribute(), the method throws this
exception. The error has been reported to Sun. Currently, there is no
workaround for this.
Container-managed persistence
for non-primitive attributes
How do I use container-managed persistence for non-primitive attributes?
First off, the attribute has to be serializable
. If it isn't, you can't use it with container-managed
persistence.
Let's say you have the three attributes you want to persist:
public String accountId; // also the primary Key
public double balance;
public mySerializable sObj;
The serializableObject can't be mapped directly,
but we can map a byte array:
public byte[] ssByteArray;
You will then have four attributes in the EJBean.
The first three will be mapped to columns in the database:
public String accountId; // primary Key
public double balance;
public byte[] sByteArray;
transient private mySerializable sObj;
In ejbLoad(),
you will convert the byte array
sByteArray
to the object of type
mySerializable.
In ejbStore(),
you will do the reverse, updating
the byte array so that the container will save it in the database as a
BLOB, or "RAW" in Oracle databases:
public void ejbLoad() throws RemoteException {
try {
ByteArrayInputStream ba =
new ByteArrayInputStream(sByteArray);
ObjectInputStream p = new ObjectInputStream(ba);
sObj = (mySerializable) p.readObject();
} catch (Exception e) {
throw new RemoteException("Exception in ejbLoad: ", e);
}
}
public void ejbStore() throws RemoteException {
try {
ByteArrayOutputStream ba = new ByteArrayOutputStream();
ObjectOutputStream p = new ObjectOutputStream(ba);
p.writeObject(sObj);
sByteArray = ba.toByteArray();
} catch (Exception e) {
throw new RemoteException("Exception in ejbLoad: ",e);
}
}
Object-relational mapping
tools
How does WebLogic make use of an object-relational mapping tool
such as JavaBlend with EJB?
Currently, you have to use bean-managed persistence to use tools such
as JavaBlend. We are looking at integrating WebLogic EJB
with object-relational tools in a future release.
Date datatypes with JDBC container-managed persistence
I'm using JDBC container-managed persistence with a Date type field in
my database. What data type attribute should I have in my EJB? The
Java Date type doesn't work.
You want java.sql.Timestamp instead of
Date. See the specific mappings by
looking in the appropriate database-specific guide:
JTS and connection pools
Is the jdbc:weblogic:jts driver being
used even when only the connection pool is referred to?
Yes -- it is implicitly being used for container-managed persistence.
Using
findByPrimaryKey()
How should I implement findByPrimaryKey()
for bean-managed persistence?
You will need to implement a method following this pattern:
public Object ejbFindByPrimaryKey(Object key)
throws FinderException
{
// Do a database query
// If query succeeds
return key;
// else
// throw FinderException
}
Matching the primary key class and database data types
Do data types of the primary key class and the database table have to
match?
They must be compatible. See mapping types
described in an earlier question.
Using primary keys and container-managed persistence
Does WebLogic EJB require a user-defined class for a primary key
when using container-managed persistence?
Yes -- check the last rule of section 9.10.7 of the EJB 1.0 specification.
The names of the fields in the primary key class must be a subset of
the names of the container-managed EJBean. Unless the primary key
class is user-defined, there is no way to satisfy this rule.
This restriction applies only to container-managed persistence.
