@Override
    public JmsJcaConnection createConnection() throws ResourceException,
                    SIException, SIErrorException {

        if (TraceComponent.isAnyTracingEnabled() && TRACE.isEntryEnabled()) {
            SibTr.entry(this, TRACE, "createConnection");
        }

        JmsJcaConnection connection = null;

        JmsJcaConnectionRequestInfo requestInfo = new JmsJcaConnectionRequestInfo();

        // Used for WAS specific code where we can relay a more useful error message to the user
        // if we receive a SINotAuthorisedException or a SIAuthenticationException when calling allocateConnection
        boolean runningInWAS = false;

        // True if we aren using container managed authentication
        boolean containerAuth = false;

        // The containter managed authentication alias (only relevant if containerAuth is true)
        String containerAlias = null;

        try {

            if (_managed) {

                /*
                 * In a managed environment obtain a managed connection
                 */

                // Obtain authentication data in case an exception is thrown. This data is then used to give a more
                // meaningful error message. The information is obtained now as it may be altered later on. This is
                // only valid when running inside WAS.
                if (_connectionManager instanceof com.ibm.ws.jca.adapter.WSConnectionManager)
                {
                    runningInWAS = true;
                    ResourceRefInfo info = ((com.ibm.ws.jca.adapter.WSConnectionManager) _connectionManager).getResourceRefInfo();
                    containerAuth = info.getAuth() == com.ibm.ws.javaee.dd.common.ResourceRef.AUTH_CONTAINER;
                    for (Property loginConfigProp : info.getLoginPropertyList())
                        if ("DefaultPrincipalMapping".equals(loginConfigProp.getName()))
                            containerAlias = loginConfigProp.getValue();
                }

                // Try and allocate a connection.

                Object object = null;
                boolean tryAgain = true;

                // Keep going around the while loop until we manage to get a valid connection
                do {

                    // Try and allocate a connection.
                    object = _connectionManager.allocateConnection(
                                                                   _managedConnectionFactory, requestInfo);

                    // Ensure that we have a session of the right type.
                    if (object instanceof JmsJcaSessionImpl) {

                        // Get the core connection from the managed connection
                        SICoreConnection coreConnection = ((JmsJcaSessionImpl) object).getManagedConnection().getCoreConnection();

                        // PM07867 It is very important that the connection request info structure
                        // has a reference to a core connection, that is connected to the same
                        // ME as our saved core connection. If a new connection was created as part of
                        // allocateConnection then this will already be the case.
                        // However, if an existing connection was re-used from the pool, no
                        // connection will have been set on the connection request info, and
                        // JCA sessions created from this JCA connection might end up connecting
                        // to different messaging engines, preventing transaction completion.
                        if (requestInfo.getSICoreConnection() == null) {
                            requestInfo.setSICoreConnection(coreConnection);
                        }

                        SICoreConnection clonedCoreConnection = null;

                        // Clone the managed connection owned core connection for use by the connection
                        // object which we will return to JCA. Previous connection failures will only
                        // become apparent here so we catch any cloning exception and handle it as a
                        // connection failure on the managed connection.

                        Exception clonedException = null;
                        if (coreConnection != null) {
                            try {
                                clonedCoreConnection = coreConnection.cloneConnection();
                            } catch (SIException e) {
                                // No FFDC code needed
                                if (TraceComponent.isAnyTracingEnabled() && TRACE.isDebugEnabled())
                                    SibTr.debug(TRACE, "Clone connection failed");
                                JmsJcaManagedConnection mc = ((JmsJcaSessionImpl) object).getManagedConnection();
                                mc.connectionErrorOccurred(e, true); // Inform JCA of connection failure on this Managed Connection
                                clonedException = e;
                            } catch (SIErrorException e) {
                                // No FFDC code needed
                                if (TraceComponent.isAnyTracingEnabled() && TRACE.isDebugEnabled())
                                    SibTr.debug(TRACE, "Clone connection failed");
                                JmsJcaManagedConnection mc = ((JmsJcaSessionImpl) object).getManagedConnection();
                                mc.connectionErrorOccurred(e, true); // Inform JCA of connection failure on this Managed Connection
                                clonedException = e;
                            }
                        }

                        if (clonedCoreConnection != null) {
                            connection = new JmsJcaConnectionImpl(this, clonedCoreConnection, (JmsJcaSessionImpl) object, requestInfo);
                        }

                        tryAgain = (clonedCoreConnection == null);

                        if (tryAgain)
                        {
                            SibTr.info(TRACE, NLS.getFormattedMessage(("CONNECTION_ERROR_RETRY_CWSJR1067"),
                                                                      new Object[] { clonedException }, null));

                            // We need to try again so we clone and change the cri (incremenet counter) which 
                            // forces j2c to create a new managed connection.  Cloning is needed to prevent
                            // a broken connection in the shared pool being returned because it has a
                            // cri == this cri (PM31826)
                            requestInfo = (JmsJcaConnectionRequestInfo) requestInfo.clone();
                            requestInfo.incrementRequestCounter();
                        }

                    } else {

                        throw new ResourceAdapterInternalException(
                                        NLS
                                                        .getFormattedMessage(
                                                                             ("EXCEPTION_RECEIVED_CWSJR1061"),
                                                                             new Object[] {
                                                                                           "createConnection",
                                                                                           JmsJcaSessionImpl.class
                                                                                                           .getName(),
                                                                                           object.getClass().getName() },
                                                                             null));

                    }

                } while (tryAgain);

            } else {

                // We are not managed.

                final SICoreConnection coreConnection = createCoreConnection();

                // Now we have enough info to create a connection we should go
                // ahead and create one.
                connection = new JmsJcaConnectionImpl(this, coreConnection, requestInfo);

            }

        } catch (final ResourceException exception)
        {
            FFDCFilter.processException(exception, CLASS_NAME
                                                   + ".createConnection", FFDC_PROBE_1, this);

            Throwable cause = exception.getCause();

            // This section will look at the cause of an exception thrown while creating a connection. If the cause
            // is a security based exeption (SIAuthenticationException or SINotAuthorizedException) then a new
            // exception is created to supply the user with more information.

            // pnickoll: We would like to pass the "cause" as a linked exception to the following exceptions
            if (runningInWAS)
            {
                if (cause instanceof SIAuthenticationException)
                {
                    SIAuthenticationException authentEx = null;
                    if (containerAuth)
                    {
                        if (containerAlias != null && !containerAlias.isEmpty()) {
                            authentEx = new SIAuthenticationException(NLS.getFormattedMessage("CONTAINER_AUTHENTICATION_EXCEPTION_1068",
                                                                                              new Object[] { containerAlias, }, null));
                        }
                        else {

                            authentEx = new SIAuthenticationException(NLS.getString("AUTHENTICATION_EXCEPTION_1077"));
                        }
                    }
                    else
                    {
                        authentEx = new SIAuthenticationException(NLS.getString("AUTHENTICATION_EXCEPTION_1077"));
                    }

                    throw authentEx;
                }
                else if (cause instanceof SINotAuthorizedException)
                {
                    if (containerAuth)
                    {
                        if (containerAlias == null)
                        {
                            throw new SINotAuthorizedException(NLS.getString("CONTAINER_AUTHORIZATION_EXCEPTION_1070"));
                        }
                    }
                    else
                    {
                        String userName = getUserName();
                        if ((userName == null) || ("".equals(userName)))
                        {
                            throw new SINotAuthorizedException(NLS.getString("CONTAINER_AUTHORIZATION_EXCEPTION_1071"));
                        }
                    }
                }
            }

            if (cause instanceof SIException)
            {
                throw (SIException) cause;
            }
            else if (cause instanceof SIErrorException)
            {
                throw (SIErrorException) cause;
            }

            throw exception;

        }

        if (TraceComponent.isAnyTracingEnabled() && TRACE.isEntryEnabled())
        {
            SibTr.exit(this, TRACE, "createConnection", connection);
        }

        return connection;
    }
@ Override public JmsJcaConnection createConnection ( ) throws ResourceException , SIException , SIErrorException { if ( TraceComponent . isAnyTracingEnabled ( ) && TRACE . isEntryEnabled ( ) ) { SibTr . entry ( this , TRACE , "createConnection" ) ; } JmsJcaConnection connection = null ; JmsJcaConnectionRequestInfo requestInfo = new JmsJcaConnectionRequestInfo ( ) ; boolean runningInWAS = false ; boolean containerAuth = false ; String containerAlias = null ; try { if ( _managed ) { if ( _connectionManager instanceof com . ibm . ws . jca . adapter . WSConnectionManager ) { runningInWAS = true ; ResourceRefInfo info = ( ( com . ibm . ws . jca . adapter . WSConnectionManager ) _connectionManager ) . getResourceRefInfo ( ) ; containerAuth = info . getAuth ( ) == com . ibm . ws . javaee . dd . common . ResourceRef . AUTH_CONTAINER ; for ( Property loginConfigProp : info . getLoginPropertyList ( ) ) if ( "DefaultPrincipalMapping" . equals ( loginConfigProp . getName ( ) ) ) containerAlias = loginConfigProp . getValue ( ) ; } Object object = null ; boolean tryAgain = true ; do { object = _connectionManager . allocateConnection ( _managedConnectionFactory , requestInfo ) ; if ( object instanceof JmsJcaSessionImpl ) { SICoreConnection coreConnection = ( ( JmsJcaSessionImpl ) object ) . getManagedConnection ( ) . getCoreConnection ( ) ; if ( requestInfo . getSICoreConnection ( ) == null ) { requestInfo . setSICoreConnection ( coreConnection ) ; } SICoreConnection clonedCoreConnection = null ; Exception clonedException = null ; if ( coreConnection != null ) { try { clonedCoreConnection = coreConnection . cloneConnection ( ) ; } catch ( SIException e ) { if ( TraceComponent . isAnyTracingEnabled ( ) && TRACE . isDebugEnabled ( ) ) SibTr . debug ( TRACE , "Clone connection failed" ) ; JmsJcaManagedConnection mc = ( ( JmsJcaSessionImpl ) object ) . getManagedConnection ( ) ; mc . connectionErrorOccurred ( e , true ) ; clonedException = e ; } catch ( SIErrorException e ) { if ( TraceComponent . isAnyTracingEnabled ( ) && TRACE . isDebugEnabled ( ) ) SibTr . debug ( TRACE , "Clone connection failed" ) ; JmsJcaManagedConnection mc = ( ( JmsJcaSessionImpl ) object ) . getManagedConnection ( ) ; mc . connectionErrorOccurred ( e , true ) ; clonedException = e ; } } if ( clonedCoreConnection != null ) { connection = new JmsJcaConnectionImpl ( this , clonedCoreConnection , ( JmsJcaSessionImpl ) object , requestInfo ) ; } tryAgain = ( clonedCoreConnection == null ) ; if ( tryAgain ) { SibTr . info ( TRACE , NLS . getFormattedMessage ( ( "CONNECTION_ERROR_RETRY_CWSJR1067" ) , new Object [ ] { clonedException } , null ) ) ; requestInfo = ( JmsJcaConnectionRequestInfo ) requestInfo . clone ( ) ; requestInfo . incrementRequestCounter ( ) ; } } else { throw new ResourceAdapterInternalException ( NLS . getFormattedMessage ( ( "EXCEPTION_RECEIVED_CWSJR1061" ) , new Object [ ] { "createConnection" , JmsJcaSessionImpl . class . getName ( ) , object . getClass ( ) . getName ( ) } , null ) ) ; } } while ( tryAgain ) ; } else { final SICoreConnection coreConnection = createCoreConnection ( ) ; connection = new JmsJcaConnectionImpl ( this , coreConnection , requestInfo ) ; } } catch ( final ResourceException exception ) { FFDCFilter . processException ( exception , CLASS_NAME + ".createConnection" , FFDC_PROBE_1 , this ) ; Throwable cause = exception . getCause ( ) ; if ( runningInWAS ) { if ( cause instanceof SIAuthenticationException ) { SIAuthenticationException authentEx = null ; if ( containerAuth ) { if ( containerAlias != null && ! containerAlias . isEmpty ( ) ) { authentEx = new SIAuthenticationException ( NLS . getFormattedMessage ( "CONTAINER_AUTHENTICATION_EXCEPTION_1068" , new Object [ ] { containerAlias , } , null ) ) ; } else { authentEx = new SIAuthenticationException ( NLS . getString ( "AUTHENTICATION_EXCEPTION_1077" ) ) ; } } else { authentEx = new SIAuthenticationException ( NLS . getString ( "AUTHENTICATION_EXCEPTION_1077" ) ) ; } throw authentEx ; } else if ( cause instanceof SINotAuthorizedException ) { if ( containerAuth ) { if ( containerAlias == null ) { throw new SINotAuthorizedException ( NLS . getString ( "CONTAINER_AUTHORIZATION_EXCEPTION_1070" ) ) ; } } else { String userName = getUserName ( ) ; if ( ( userName == null ) || ( "" . equals ( userName ) ) ) { throw new SINotAuthorizedException ( NLS . getString ( "CONTAINER_AUTHORIZATION_EXCEPTION_1071" ) ) ; } } } } if ( cause instanceof SIException ) { throw ( SIException ) cause ; } else if ( cause instanceof SIErrorException ) { throw ( SIErrorException ) cause ; } throw exception ; } if ( TraceComponent . isAnyTracingEnabled ( ) && TRACE . isEntryEnabled ( ) ) { SibTr . exit ( this , TRACE , "createConnection" , connection ) ; } return connection ; }
Creates a new <code>JmsJcaConnection</code>. An empty
<code>JmsJcaConnectionRequestInfo</code> object is passed to the
<code>allocateConnection</code> method of the associated connection
manager. This returns a new <code>JmsJcaSession</code> from which the
associated <code>JmsJcaConnnection</code> can be obtained. This will
contain a core connection authenticated with the credentials from the
container or, if none are passed, those from the managed connection
factory. The session is held by the connection and returned on the first
call to <code>createSession</code>.

@return the connection
@throws javax.resource.ResourceException
if the JCA runtime fails to allocate a connection
@throws SIException
if the creation of the core connection fails
@throws SIErrorException
if the creation of the core connection fails