This one time, at band camp, David Jencks said:

DJ>You might get more response if you included jboss version, castor version,
DJ>deployment info, and a code snippet.
DJ>
DJ>david jencks
DJ>
DJ>On 2002.08.02 13:21:13 -0400 Bruce Snyder wrote:
DJ>> This one time, at band camp, Bruce Snyder said:
DJ>> 
DJ>> BS>I'm building an application that is using Castor for persisting
DJ>> objects
DJ>> BS>and I'm using the JBoss TransactionManager for container managed
DJ>> BS>transactions. Inside of TransactionManager.getThreadInfo(), there's a
DJ>> BS>call to:
DJ>> BS>
DJ>> BS>    ThreadInfo ret = (ThreadInfo)threadTx.get();
DJ>> BS>
DJ>> BS>This call instantiates the ThreadInfo inner class and sets the
DJ>> following: 
DJ>> BS>
DJ>> BS>    long timeout = 0;
DJ>> BS>    TransactionImpl tx = null;
DJ>> BS>
DJ>> BS>The problem with this is that the tx object is then null. This null
DJ>> BS>tx object is sent back to Castor to use and because it's null, a
DJ>> BS>NullPointerException is thrown every time. The extremely odd thing is
DJ>> BS>that after running my test and receiving the NPE, I wait a bit and I
DJ>> BS>see the following message come across the log file:
DJ>> BS>
DJ>> BS>    [WARN,TxCapsule] Transaction XidImpl [FormatId=257,
DJ>> GlobalId=bsnyderlnx.xyz.com//0, BranchQual=] timed out.
DJ>> status=STATUS_ACTIVE
DJ>> BS>
DJ>> BS>So I have two questions about this scenario: 
DJ>> BS>
DJ>> BS>      1) Is this possibly a timing issue whereby the transaction is
DJ>> not
DJ>> BS>      created immediately? If so, maybe I could sleep for a bit to see
DJ>> BS>      if the transaction is actually created.
DJ>> BS>
DJ>> BS>      2) Has anyone else encountered this or have I possibly
DJ>> configured
DJ>> BS>      something incorrectly?
DJ>> 
DJ>> BTW, I forgot to mention that I've changed to Bean Managed Transactions
DJ>> and I'm still receiving the NullPointerException.

My apologies. Thanks for the reminder, David. This is going to be a
bit long.

I'm using JBoss 2.4.4 and Castor 0.9.3.9-19. The deployement descriptors
and source are as follows:

-----------------------------------------------------------------------

The ejb-jar.xml: 

<ejb-jar >

    <description>No Description.</description>
    <display-name>Generated by XDoclet</display-name>

    <enterprise-beans>

        <session >
            <description><![CDATA[A Session Bean providing the PlanLock 
Service.]]></description>

            <ejb-name>PlanLockService</ejb-name>

            
<home>com.digitalglobe.mp.interfaces.system.db.planlock.PlanLockServiceHome</home>
            
<remote>com.digitalglobe.mp.interfaces.system.db.planlock.PlanLockService</remote>
            
<ejb-class>com.digitalglobe.mp.interfaces.system.db.planlock.PlanLockServiceBean</ejb-class>
            <session-type>Stateful</session-type>
            <transaction-type>Bean</transaction-type>

            <resource-ref>
                <res-ref-name>jdo/LTPJDO</res-ref-name>
                <res-type>org.exolab.castor.jdo.DataObjects</res-type>
                <res-auth>Container</res-auth>
            </resource-ref>
        </session>

    </enterprise-beans>

    <assembly-descriptor >

    </assembly-descriptor>

</ejb-jar>

-----------------------------------------------------------------------

The jboss.xml: 

<jboss>

<enterprise-beans>

    <session>
        <ejb-name>PlanLockService</ejb-name>
        <jndi-name>comp/env/ejb/service/PlanLockService</jndi-name>
        <resource-ref>
            <res-ref-name>jdo/LTPJDO</res-ref-name>
            <resource-name>LTPJDO</resource-name>
        </resource-ref>
    </session>

</enterprise-beans>

<resource-managers>
    <resource-manager res-class="org.jboss.ejb.deployment.CastorJDOResource">
        <res-name>LTPJDO</res-name>
        <res-jndi-name>java:/LTPJDO</res-jndi-name>
    </resource-manager>
</resource-managers>

</jboss>

-----------------------------------------------------------------------

My client code fails in the follow block on the addLock() call: 

    service.startSession();
    service.addLock( planLock );

-----------------------------------------------------------------------

The startSession() method: 

    public void startSession() throws DAOException, RemoteException
    {
        try 
        {
            UserTransaction userTx = context.getUserTransaction();
            userTx.begin();
        } 
        catch ( Exception ex ) 
        {
            throw new DAOException( "Error starting transaction: ", ex );
        }
    }

-----------------------------------------------------------------------

The addLock() method: 

    public void addLock( PlanLock newLock ) throws DAOException, LockOverlapException, 
RemoteException
    {
        Collection ret = null;
        Collection intersecting = findPlanLockIntersects( newLock.getInterval() );

        if ( intersecting.size() == 0 ) 
        {
            planLockDAO.insertObject( newLock );
        }
        else 
        {
            throw new LockOverlapException();
        }
    }

-----------------------------------------------------------------------

The findPlanLockIntersects() method: 

    public Collection findPlanLockIntersects( EEpochInterval intvl ) 
        throws DAOException, RemoteException 
    {
        TimeZone.setDefault(new SimpleTimeZone(0, "GMT"));
        Object[] paramValues;

        EEpochTime stime = intvl.getStart();
        EEpochTime etime = intvl.getEnd();

        Date startDate = stime.getCalendar().getTime();
        Date endDate   = etime.getCalendar().getTime();

        startDate.setTime( startDate.getTime() - 1 );
        endDate.setTime( endDate.getTime() + 1 );
        paramValues = new Object[] { startDate, endDate };

        StringBuffer filter = new StringBuffer();
        filter.append( "(start >= $1 and start < $2) " );
        filter.append( "or (end > $1 and end <= $2) " );
        filter.append( "or (start <= $1 and end >= $2)" );
        filter.append( "or (start >= $1 and end <= $2)" );

        Collection planLocks = planLockDAO.findByFilter( filter.toString(), 
paramValues );

        return planLocks;
    }

-----------------------------------------------------------------------

The findByFilter() methods: 

public Collection findByFilter( String filter ) throws DAOException 
{
    return findByFilter( filter, null );
}

public Collection findByFilter( String filter, Object[] paramValues ) throws 
DAOException 
{
    Database db = null;
    Collection returnObjs = null;
    try 
    {
        db = jdo.getDatabase();
        returnObjs = extract( db, filter,paramValues );
    } 
    catch ( DAOException e ) 
    {
        throw e;
    } 
    catch ( Exception e ) 
    {
        throw new DAOExtractException( e );
    } 
    finally 
    {
        if ( db != null ) 
        {
            try 
            {
                db.close();
            } 
            catch ( Exception e ) 
            { 
                e.printStackTrace(); 
            }
    }
    return returnObjs;
}

-----------------------------------------------------------------------

Notice that the findByFilter( String filter, Object[] paramValues )
method above calls jdo.getDatabase(). The call to getDatabase() goes
into org.exolab.castor.jdo.JDO.getDatabase() and winds up failing with
the NullPointerException on line #603 where it calls tx.getStatus():

    599    tx = tm.getTransaction();
    600    if ( _txDbPool != null && _txDbPool.containsTx( tx ) )
    601        return _txDbPool.get( tx );
    602
    603    if ( tx.getStatus() == Status.STATUS_ACTIVE ) {

The problem occurs in line #599 when getTransaction() returns a null
object from org.jboss.tm.TxManager.getTransaction():

    public Transaction getTransaction()
    throws SystemException
    {
        ThreadInfo ti = getThreadInfo();
        TransactionImpl current = ti.tx;

        if (current != null && current.isDone()) {
            ti.tx = null;
            return null;
        }
        return current;
    }

The current object is returned as null due to the ThreadInfo inner class:

   static class ThreadInfo
   {
       long timeout = 0;
       TransactionImpl tx = null;
   }

The current object winds up being null because the tx object is assigned
to null in the ThreadInfo class listed above.

I'm not sure why the tx object is assinged to null rather than to a
valid TransactionImpl object. However, like I said, if I wait a bit I
see the following come across the log file:

    WARN,TxCapsule] Transaction XidImpl [FormatId=257,
    GlobalId=bsnyderlnx.digitalglobe.com//1, BranchQual=] timed
    out. status=STATUS_ACTIVE

I'm not exactly sure what the above statement means exactly, but I
interpret it as meaning that a Transaction object whose XidImpl object
contains a FormatId of 257 was just set to STATUS_ACTIVE. I believe this
is what I need - an active Transaction object.

So why is the tx object not materialized into a full TransactionImpl
object and passed back to Castor? Did I configure something incorrectly?

Bruce
-- 
perl -e 'print unpack("u30","<0G)U8V4\@4VYY9&5R\"F9E<G)E=\$\!F<FEI+F-O;0\`\`");'



-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
JBoss-user mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/jboss-user

Reply via email to