Search in sources :

Example 1 with CreationException

use of jakarta.enterprise.inject.CreationException in project helidon by oracle.

the class ExtendedEntityManager method acquireDelegate.

/*
     * Instance methods.
     */
/**
 * Acquires and returns the delegate {@link EntityManager} that
 * this {@link ExtendedEntityManager} must use according to the
 * rules for extended persistence contexts spelled out in the JPA
 * specification.
 *
 * <p>This method never returns {@code null}.</p>
 *
 * @return the delegate {@link EntityManager}; never {@code null}
 */
@Override
@SuppressWarnings("checkstyle:MethodLength")
protected EntityManager acquireDelegate() {
    // This is very tricky.  Pay attention.
    // 
    // An extended EntityManager's persistence context (its "bag"
    // of "managed", not "detached", entities) spans transactions.
    // 
    // In this CDI-centric implementation, we make use of
    // jakarta.transaction.TransactionScoped to serve up
    // EntityManager instances in true JTA transaction scope.
    // That means those objects are destroyed when the transaction
    // is destroyed.  Obviously therefore they cannot be used as
    // the sole basis for the transaction-respecting bits of an
    // extended EntityManager.
    // 
    // However, an extended EntityManager must "become" the sole
    // EntityManager associated with a JTA transaction, and then
    // must dissociate from it after it has committed or rolled
    // back.
    // 
    // So we make use of the fact that the @TransactionScoped bean
    // that has been installed is going to produce instances of
    // CdiTransactionScopedEntityManager.  This
    // DelegatingEntityManager subclass allows you to set _its_
    // delegate, provided it has not yet been set, and allows you
    // to control whether or not its delegate is actually closed
    // when _it_ is closed.  This lets us "tunnel" another
    // EntityManager "into" transaction scope.
    final EntityManager returnValue;
    final Context context = transactionSupport.getContext();
    if (context == null || !context.isActive()) {
        if (this.delegate == null) {
            assert this.subdelegate == null;
            // For the first time during the lifespan of this
            // object, create its delegate.  It will be a "normal"
            // EntityManager.  We don't set our subdelegate
            // because that is only set in transactional cases
            // (see below).
            this.delegate = EntityManagers.createContainerManagedEntityManager(this.instance, this.suppliedQualifiers);
        } else if (this.delegate instanceof CdiTransactionScopedEntityManager) {
            // (see later in this method for proof).
            assert this.subdelegate != null;
            assert !(this.subdelegate instanceof CdiTransactionScopedEntityManager);
            assert this.subdelegate.isOpen();
            // We are an extended EntityManager, so take that old
            // "normal" EntityManager subdelegate that we know was
            // "tunneled" into our "stale"
            // CdiTransactionScopedEntityManager delegate, and
            // "pull it out" to be our delegate.  We can discard
            // the stale CdiTransactionScopedEntityManager at this
            // point, which we do by just overwriting its
            // reference.
            this.delegate = this.subdelegate;
            // Now set our subdelegate to null to help indicate that
            // we're no longer in a transactional situation.
            this.subdelegate = null;
        }
        // situation.
        assert this.delegate != null;
        assert !(this.delegate instanceof CdiTransactionScopedEntityManager);
        assert this.delegate.isOpen();
        assert this.subdelegate == null;
        returnValue = this.delegate;
    } else {
        if (this.delegate != null && !this.delegate.isOpen()) {
            // subdelegate field.
            assert this.delegate instanceof CdiTransactionScopedEntityManager;
            assert this.subdelegate != null;
            assert !(this.subdelegate instanceof CdiTransactionScopedEntityManager);
            assert this.subdelegate.isOpen();
            this.delegate = this.subdelegate;
            this.subdelegate = null;
        }
        if (!(this.delegate instanceof CdiTransactionScopedEntityManager)) {
            // not a CdiTransactionScopedEntityManager.
            assert this.subdelegate == null;
            assert this.delegate == null ? true : this.delegate.isOpen();
            // Since we're in a transaction, we have to look for
            // the @TransactionScoped EntityManager that is
            // associated with the JTA transaction.  So look for
            // an EntityManager bean annotated with, among other
            // possible things, @CdiTransactionScoped
            // and @ContainerManaged.
            final Set<Annotation> selectionQualifiers = new HashSet<>(this.suppliedQualifiers);
            selectionQualifiers.remove(Extended.Literal.INSTANCE);
            selectionQualifiers.remove(JpaTransactionScoped.Literal.INSTANCE);
            selectionQualifiers.remove(NonTransactional.Literal.INSTANCE);
            selectionQualifiers.add(CdiTransactionScoped.Literal.INSTANCE);
            selectionQualifiers.add(ContainerManaged.Literal.INSTANCE);
            final Set<Bean<?>> cdiTransactionScopedEntityManagerBeans = this.beanManager.getBeans(CdiTransactionScopedEntityManager.class, selectionQualifiers.toArray(new Annotation[selectionQualifiers.size()]));
            assert cdiTransactionScopedEntityManagerBeans != null;
            assert !cdiTransactionScopedEntityManagerBeans.isEmpty();
            @SuppressWarnings("unchecked") final Bean<?> cdiTransactionScopedEntityManagerBean = (Bean<CdiTransactionScopedEntityManager>) this.beanManager.resolve(cdiTransactionScopedEntityManagerBeans);
            assert cdiTransactionScopedEntityManagerBean != null;
            assert context.getScope().equals(cdiTransactionScopedEntityManagerBean.getScope());
            // Using that bean, check the Context to see if there's
            // already a container-managed EntityManager enrolled in
            // the transaction (without accidentally creating a new
            // one, hence the single-argument Context#get(Contextual)
            // invocation, not the dual-argument
            // Context#get(Contextual, CreationalContext) one).  We
            // have to do this to honor section 7.6.3.1 of the JPA
            // specification.
            final Object existingContainerManagedCdiTransactionScopedEntityManager = context.get(cdiTransactionScopedEntityManagerBean);
            if (existingContainerManagedCdiTransactionScopedEntityManager != null) {
                // transactional or not.
                throw new CreationException(Messages.format("preexistingExtendedEntityManager", cdiTransactionScopedEntityManagerBean, existingContainerManagedCdiTransactionScopedEntityManager));
            }
            // OK, there's no existing CDI-transaction-scoped
            // EntityManager.  Let's cause one to be created.
            @SuppressWarnings("unchecked") final CdiTransactionScopedEntityManager cdiTransactionScopedEntityManager = (CdiTransactionScopedEntityManager) this.beanManager.getReference(cdiTransactionScopedEntityManagerBean, CdiTransactionScopedEntityManager.class, this.beanManager.createCreationalContext(cdiTransactionScopedEntityManagerBean));
            assert cdiTransactionScopedEntityManager != null;
            // "through" to be *its* delegate.
            if (this.delegate == null) {
                this.subdelegate = EntityManagers.createContainerManagedEntityManager(this.instance, this.suppliedQualifiers);
            } else {
                assert !(this.delegate instanceof CdiTransactionScopedEntityManager);
                assert this.subdelegate == null;
                this.subdelegate = this.delegate;
            }
            assert this.subdelegate != null;
            cdiTransactionScopedEntityManager.setDelegate(this.subdelegate);
            this.delegate = cdiTransactionScopedEntityManager;
            // extended EntityManager.
            if (this.isSynchronized) {
                this.delegate.joinTransaction();
            }
        }
        assert this.delegate != null;
        assert this.delegate.isOpen();
        returnValue = this.delegate;
    }
    return returnValue;
}
Also used : Context(jakarta.enterprise.context.spi.Context) EntityManager(jakarta.persistence.EntityManager) CreationException(jakarta.enterprise.inject.CreationException) Annotation(java.lang.annotation.Annotation) HashSet(java.util.HashSet) Bean(jakarta.enterprise.inject.spi.Bean)

Example 2 with CreationException

use of jakarta.enterprise.inject.CreationException in project helidon by oracle.

the class JedisExtension method addBeans.

private void addBeans(@Observes final AfterBeanDiscovery event, final BeanManager beanManager) throws IntrospectionException {
    if (event != null && beanManager != null) {
        for (final String instanceName : this.instanceNames) {
            if (instanceName != null) {
                final Set<Annotation> qualifiers;
                if (instanceName.equals("default")) {
                    qualifiers = Collections.singleton(Default.Literal.INSTANCE);
                } else {
                    qualifiers = Collections.singleton(NamedLiteral.of(instanceName));
                }
                event.<JedisPoolConfig>addBean().addTransitiveTypeClosure(JedisPoolConfig.class).scope(ApplicationScoped.class).addQualifiers(qualifiers).produceWith((instance) -> {
                    final JedisPoolConfig returnValue = new JedisPoolConfig();
                    try {
                        this.configure(instance.select(Config.class).get(), returnValue, JedisPoolConfig.class, instanceName);
                    } catch (final IntrospectionException | ReflectiveOperationException e) {
                        throw new CreationException(e.getMessage(), e);
                    }
                    return returnValue;
                });
                final Annotation[] qualifiersArray = qualifiers.toArray(new Annotation[qualifiers.size()]);
                event.<JedisPool>addBean().addTransitiveTypeClosure(JedisPool.class).scope(ApplicationScoped.class).addQualifiers(qualifiers).produceWith(instance -> {
                    return produceJedisPool(instance, instanceName, qualifiersArray);
                }).disposeWith((p, instance) -> p.destroy());
                event.<Jedis>addBean().addTransitiveTypeClosure(Jedis.class).scope(Dependent.class).addQualifiers(qualifiers).produceWith(instance -> instance.select(JedisPool.class, qualifiersArray).get().getResource()).disposeWith((j, instance) -> j.close());
            }
        }
    }
}
Also used : Dependent(jakarta.enterprise.context.Dependent) Observes(jakarta.enterprise.event.Observes) SSLParameters(javax.net.ssl.SSLParameters) ApplicationScoped(jakarta.enterprise.context.ApplicationScoped) HashMap(java.util.HashMap) ProcessInjectionPoint(jakarta.enterprise.inject.spi.ProcessInjectionPoint) Instance(jakarta.enterprise.inject.Instance) Default(jakarta.enterprise.inject.Default) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) Introspector(java.beans.Introspector) BeanInfo(java.beans.BeanInfo) Map(java.util.Map) JedisPool(redis.clients.jedis.JedisPool) HostnameVerifier(javax.net.ssl.HostnameVerifier) Method(java.lang.reflect.Method) BeanManager(jakarta.enterprise.inject.spi.BeanManager) CreationException(jakarta.enterprise.inject.CreationException) InjectionPoint(jakarta.enterprise.inject.spi.InjectionPoint) NamedLiteral(jakarta.enterprise.inject.literal.NamedLiteral) Set(java.util.Set) Config(org.eclipse.microprofile.config.Config) IntrospectionException(java.beans.IntrospectionException) SSLSocketFactory(javax.net.ssl.SSLSocketFactory) Objects(java.util.Objects) Protocol(redis.clients.jedis.Protocol) ParameterizedType(java.lang.reflect.ParameterizedType) AfterBeanDiscovery(jakarta.enterprise.inject.spi.AfterBeanDiscovery) Type(java.lang.reflect.Type) Provider(jakarta.inject.Provider) Jedis(redis.clients.jedis.Jedis) PropertyDescriptor(java.beans.PropertyDescriptor) Annotation(java.lang.annotation.Annotation) Optional(java.util.Optional) JedisPoolConfig(redis.clients.jedis.JedisPoolConfig) Collections(java.util.Collections) Named(jakarta.inject.Named) IntrospectionException(java.beans.IntrospectionException) CreationException(jakarta.enterprise.inject.CreationException) Dependent(jakarta.enterprise.context.Dependent) ApplicationScoped(jakarta.enterprise.context.ApplicationScoped) JedisPoolConfig(redis.clients.jedis.JedisPoolConfig) Annotation(java.lang.annotation.Annotation)

Example 3 with CreationException

use of jakarta.enterprise.inject.CreationException in project helidon by oracle.

the class NarayanaExtension method afterBeanDiscovery.

/*
     * Instance methods.
     */
/**
 * Adds a synthetic bean that creates a {@link Transaction} in
 * {@linkplain TransactionScoped transaction scope}.
 *
 * @param event the {@link AfterBeanDiscovery} event fired by the
 * CDI container; may be {@code null} in which case no action will
 * be taken
 *
 * @param beanManager the {@link BeanManager} in effect; may be
 * {@code null} in which case no action will be taken
 */
private void afterBeanDiscovery(@Observes final AfterBeanDiscovery event, final BeanManager beanManager) {
    final String cn = NarayanaExtension.class.getName();
    final String mn = "afterBeanDiscovery";
    if (LOGGER.isLoggable(Level.FINER)) {
        LOGGER.entering(cn, mn, new Object[] { event, beanManager });
    }
    if (event != null && beanManager != null) {
        // Weld registers a UserTransaction bean well before this
        // observer method fires.  OpenWebBeans does not.  We need
        // to handle both cases since this is not part of the CDI
        // specification.
        Collection<? extends Bean<?>> beans = beanManager.getBeans(UserTransaction.class);
        if (beans == null || beans.isEmpty()) {
            event.addBean().types(UserTransaction.class).addQualifiers(Any.Literal.INSTANCE, Default.Literal.INSTANCE).scope(Dependent.class).createWith(cc -> com.arjuna.ats.jta.UserTransaction.userTransaction());
            if (LOGGER.isLoggable(Level.FINE)) {
                LOGGER.logp(Level.FINE, cn, mn, "addedUserTransactionBean");
            }
        }
        event.addBean().id(Transaction.class.getName()).types(Transaction.class).addQualifiers(Any.Literal.INSTANCE, // OpenWebBeans does not add these
        Default.Literal.INSTANCE).scope(TransactionScoped.class).createWith(cc -> {
            try {
                return CDI.current().select(TransactionManager.class).get().getTransaction();
            } catch (final SystemException systemException) {
                throw new CreationException(systemException.getMessage(), systemException);
            }
        });
        if (LOGGER.isLoggable(Level.FINE)) {
            LOGGER.logp(Level.FINE, cn, mn, "addedTransactionBean");
        }
        beans = beanManager.getBeans(JTAEnvironmentBean.class);
        if (beans == null || beans.isEmpty()) {
            event.addBean().addTransitiveTypeClosure(JTAEnvironmentBean.class).addQualifiers(Any.Literal.INSTANCE, Default.Literal.INSTANCE).scope(Singleton.class).createWith(cc -> DEFAULT_JTA_ENVIRONMENT_BEAN);
            if (LOGGER.isLoggable(Level.FINE)) {
                LOGGER.logp(Level.FINE, cn, mn, "addedJtaEnvironmentBeanBean");
            }
        }
    }
    if (LOGGER.isLoggable(Level.FINER)) {
        LOGGER.exiting(cn, mn);
    }
}
Also used : UserTransaction(jakarta.transaction.UserTransaction) Transaction(jakarta.transaction.Transaction) UserTransaction(jakarta.transaction.UserTransaction) SystemException(jakarta.transaction.SystemException) Singleton(jakarta.inject.Singleton) CreationException(jakarta.enterprise.inject.CreationException) Dependent(jakarta.enterprise.context.Dependent) JTAEnvironmentBean(com.arjuna.ats.jta.common.JTAEnvironmentBean) TransactionScoped(jakarta.transaction.TransactionScoped)

Example 4 with CreationException

use of jakarta.enterprise.inject.CreationException in project helidon by oracle.

the class JpaExtension method maybeAddPersistenceProviderBean.

/**
 * Given a {@link PersistenceUnitInfo} and a {@link Collection} of
 * {@link PersistenceProvider} instances representing already
 * "beanified" {@link PersistenceProvider}s, adds a CDI bean for
 * the {@linkplain
 * PersistenceUnitInfo#getPersistenceProviderClassName()
 * persistence provider referenced by the supplied
 * <code>PersistenceUnitInfo</code>} if the supplied {@link
 * Collection} of {@link PersistenceProvider}s does not contain
 * an instance of it.
 *
 * @param event the {@link AfterBeanDiscovery} event that will do
 * the actual bean addition; must not be {@code null}
 *
 * @param persistenceUnitInfo the {@link PersistenceUnitInfo}
 * whose {@linkplain
 * PersistenceUnitInfo#getPersistenceProviderClassName()
 * associated persistence provider} will be beanified; must not be
 * {@code null}
 *
 * @param providers a {@link Collection} of {@link
 * PersistenceProvider} instances that represent {@link
 * PersistenceProvider}s that have already had beans added for
 * them; may be {@code null}
 *
 * @exception NullPointerException if {@code event} or {@code
 * persistenceUnitInfo} is {@code null}
 *
 * @exception ReflectiveOperationException if an error occurs
 * during reflection
 */
private void maybeAddPersistenceProviderBean(final AfterBeanDiscovery event, final PersistenceUnitInfo persistenceUnitInfo, final Collection<? extends PersistenceProvider> providers) throws ReflectiveOperationException {
    final String cn = JpaExtension.class.getName();
    final String mn = "maybeAddPersistenceProviderBean";
    if (LOGGER.isLoggable(Level.FINER)) {
        LOGGER.entering(cn, mn, new Object[] { event, persistenceUnitInfo, providers });
    }
    Objects.requireNonNull(event);
    Objects.requireNonNull(persistenceUnitInfo);
    final String providerClassName = persistenceUnitInfo.getPersistenceProviderClassName();
    if (providerClassName != null) {
        boolean add = true;
        if (providers != null && !providers.isEmpty()) {
            for (final PersistenceProvider provider : providers) {
                if (provider != null && provider.getClass().getName().equals(providerClassName)) {
                    add = false;
                    break;
                }
            }
        }
        if (add) {
            // The PersistenceProvider class in question is not one we
            // already loaded.  Add a bean for it too.
            String persistenceUnitName = persistenceUnitInfo.getPersistenceUnitName();
            if (persistenceUnitName == null || persistenceUnitName.isEmpty()) {
                persistenceUnitName = DEFAULT_PERSISTENCE_UNIT_NAME;
                this.defaultPersistenceUnitInEffect = true;
            }
            // Provide support for, e.g.:
            // @Inject
            // @Named("test")
            // private PersistenceProvider providerProbablyReferencedFromAPersistenceXml;
            event.addBean().types(PersistenceProvider.class).scope(ApplicationScoped.class).addQualifiers(NamedLiteral.of(persistenceUnitName)).createWith(cc -> {
                try {
                    ClassLoader classLoader = persistenceUnitInfo.getClassLoader();
                    if (classLoader == null) {
                        classLoader = Thread.currentThread().getContextClassLoader();
                    }
                    assert classLoader != null;
                    @SuppressWarnings("unchecked") final Class<? extends PersistenceProvider> c = (Class<? extends PersistenceProvider>) Class.forName(providerClassName, true, classLoader);
                    return c.getDeclaredConstructor().newInstance();
                } catch (final ReflectiveOperationException reflectiveOperationException) {
                    throw new CreationException(reflectiveOperationException.getMessage(), reflectiveOperationException);
                }
            });
        }
    }
    if (LOGGER.isLoggable(Level.FINER)) {
        LOGGER.exiting(cn, mn);
    }
}
Also used : PersistenceProvider(jakarta.persistence.spi.PersistenceProvider) URLClassLoader(java.net.URLClassLoader) CreationException(jakarta.enterprise.inject.CreationException)

Aggregations

CreationException (jakarta.enterprise.inject.CreationException)4 Dependent (jakarta.enterprise.context.Dependent)2 Annotation (java.lang.annotation.Annotation)2 HashSet (java.util.HashSet)2 JTAEnvironmentBean (com.arjuna.ats.jta.common.JTAEnvironmentBean)1 ApplicationScoped (jakarta.enterprise.context.ApplicationScoped)1 Context (jakarta.enterprise.context.spi.Context)1 Observes (jakarta.enterprise.event.Observes)1 Default (jakarta.enterprise.inject.Default)1 Instance (jakarta.enterprise.inject.Instance)1 NamedLiteral (jakarta.enterprise.inject.literal.NamedLiteral)1 AfterBeanDiscovery (jakarta.enterprise.inject.spi.AfterBeanDiscovery)1 Bean (jakarta.enterprise.inject.spi.Bean)1 BeanManager (jakarta.enterprise.inject.spi.BeanManager)1 InjectionPoint (jakarta.enterprise.inject.spi.InjectionPoint)1 ProcessInjectionPoint (jakarta.enterprise.inject.spi.ProcessInjectionPoint)1 Named (jakarta.inject.Named)1 Provider (jakarta.inject.Provider)1 Singleton (jakarta.inject.Singleton)1 EntityManager (jakarta.persistence.EntityManager)1