/**
   * Loads the persistence provider adapter
   *
   * @param adapterModule may specify the adapter module name (can be null to use noop provider)
   * @return the persistence provider adaptor for the provider class
   * @throws ModuleLoadException
   */
  public static PersistenceProviderAdaptor loadPersistenceAdapterModule(String adapterModule)
      throws ModuleLoadException {
    final ModuleLoader moduleLoader = Module.getBootModuleLoader();

    if (adapterModule == null) {
      return noopAdaptor;
    }

    PersistenceProviderAdaptor persistenceProviderAdaptor = null;

    Module module = moduleLoader.loadModule(ModuleIdentifier.fromString(adapterModule));
    final ServiceLoader<PersistenceProviderAdaptor> serviceLoader =
        module.loadService(PersistenceProviderAdaptor.class);
    if (serviceLoader != null) {
      for (PersistenceProviderAdaptor adaptor : serviceLoader) {
        if (persistenceProviderAdaptor != null) {
          throw MESSAGES.multipleAdapters(adapterModule);
        }
        persistenceProviderAdaptor = adaptor;
        JPA_LOGGER.debugf("loaded persistence provider adapter %s", adapterModule);
      }
      if (persistenceProviderAdaptor != null) {
        persistenceProviderAdaptor.injectJtaManager(JtaManagerImpl.getInstance());
      }
    }

    return persistenceProviderAdaptor;
  }
  /**
   * Loads the persistence provider adapter
   *
   * @param persistenceProvider classloader will be used to load the persistence provider adapter
   * @return the persistence provider adaptor for the provider class
   */
  public static PersistenceProviderAdaptor loadPersistenceAdapter(
      PersistenceProvider persistenceProvider) {
    PersistenceProviderAdaptor persistenceProviderAdaptor = null;

    final ServiceLoader<PersistenceProviderAdaptor> serviceLoader =
        ServiceLoader.load(
            PersistenceProviderAdaptor.class, persistenceProvider.getClass().getClassLoader());

    if (serviceLoader != null) {
      for (PersistenceProviderAdaptor adaptor : serviceLoader) {
        if (persistenceProviderAdaptor != null) {
          throw MESSAGES.classloaderHasMultipleAdapters(
              persistenceProvider.getClass().getClassLoader().toString());
        }
        persistenceProviderAdaptor = adaptor;
        JPA_LOGGER.debugf(
            "loaded persistence provider adapter %s from classloader %s",
            persistenceProviderAdaptor.getClass().getName(),
            persistenceProvider.getClass().getClassLoader().toString());
      }
      if (persistenceProviderAdaptor != null) {
        persistenceProviderAdaptor.injectJtaManager(JtaManagerImpl.getInstance());
      }
    }

    return persistenceProviderAdaptor == null ? noopAdaptor : persistenceProviderAdaptor;
  }
 /**
  * Create EE container entity manager factory
  *
  * @return EntityManagerFactory
  */
 private EntityManagerFactory createContainerEntityManagerFactory() {
   persistenceProviderAdaptor.beforeCreateContainerEntityManagerFactory(pu);
   try {
     JPA_LOGGER.tracef(
         "calling createContainerEntityManagerFactory for pu=%s with integration properties=%s, application properties=%s",
         pu.getScopedPersistenceUnitName(), properties.getValue(), pu.getProperties());
     return persistenceProvider.createContainerEntityManagerFactory(pu, properties.getValue());
   } finally {
     try {
       persistenceProviderAdaptor.afterCreateContainerEntityManagerFactory(pu);
     } finally {
       pu.setAnnotationIndex(
           null); // close reference to Annotation Index (only needed during call to
                  // createContainerEntityManagerFactory)
       // This is needed if the datasource is restarted
       // pu.setTempClassLoaderFactory(null);    // close reference to temp classloader factory
       // (only needed during call to createEntityManagerFactory)
     }
   }
 }