Program: 63421
Project: 63421
Buggy source:
/** 
 * Deploy a persistence session and return an EntityManagerFactory. Deployment takes a session that was partially created in the predeploy call and makes it whole. This means doing any configuration that requires the real class definitions for the entities.  In the predeploy phase we were in a stage where we were not let allowed to load the real classes. Deploy could be called several times - but only the first call does the actual deploying - additional calls allow to update session properties (in case the session is not connected). Note that there is no need to synchronize deploy method - it doesn't alter factoryCount and while deploy is executed no other method can alter the current state (predeploy call would just increment factoryCount; undeploy call would not drop factoryCount to 0). However precautions should be taken to handle concurrent calls to deploy, because those may alter the current state or connect the session.
 * @param realClassLoader The class loader that was used to load the entity classes. This loaderwill be maintained for the lifespan of the loaded classes.
 * @param additionalProperties added to persistence unit properties for updateServerSession overriding existing properties.In JSE case it allows to alter properties in main (as opposed to preMain where preDeploy is called).
 * @return An EntityManagerFactory to be used by the Container to obtain EntityManagers
 */
public AbstractSession deploy(ClassLoader realClassLoader,Map additionalProperties){
  if (this.state != STATE_PREDEPLOYED && this.state != STATE_DEPLOYED && this.state != STATE_HALF_DEPLOYED) {
    if (mustBeCompositeMember()) {
      throw new PersistenceException(EntityManagerSetupException.compositeMemberCannotBeUsedStandalone(this.persistenceUnitInfo.getPersistenceUnitName()));
    }
    throw new PersistenceException(EntityManagerSetupException.cannotDeployWithoutPredeploy(this.persistenceUnitInfo.getPersistenceUnitName(),this.state,this.persistenceException));
  }
  this.session.log(SessionLog.FINEST,SessionLog.JPA,"String_Node_Str",new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(),this.session.getName(),this.state,this.factoryCount});
  ClassLoader classLoaderToUse=realClassLoader;
  if (additionalProperties.containsKey(PersistenceUnitProperties.CLASSLOADER)) {
    classLoaderToUse=(ClassLoader)additionalProperties.get(PersistenceUnitProperties.CLASSLOADER);
  }
 else   if ((this.processor != null) && (this.processor.getProject() != null) && (this.processor.getProject().hasVirtualClasses())&& (this.state == STATE_PREDEPLOYED)&& (!(classLoaderToUse instanceof DynamicClassLoader))) {
    classLoaderToUse=new DynamicClassLoader(classLoaderToUse);
  }
  boolean isLockAcquired=false;
  try {
    Map deployProperties=mergeMaps(additionalProperties,this.persistenceUnitInfo.getProperties());
    updateTunerPreDeploy(deployProperties,classLoaderToUse);
    translateOldProperties(deployProperties,this.session);
    if (isComposite()) {
      updateCompositeMembersProperties(deployProperties);
    }
    if (this.state == STATE_PREDEPLOYED) {
      this.deployLock.acquire();
      isLockAcquired=true;
      if (this.state == STATE_PREDEPLOYED) {
        if (this.shouldBuildProject && !this.isSessionLoadedFromSessionsXML) {
          if (isComposite()) {
            deployCompositeMembers(deployProperties,classLoaderToUse);
          }
 else {
            if (this.processor.getMetadataSource() != null) {
              Map metadataProperties=this.processor.getMetadataSource().getPropertyOverrides(deployProperties,classLoaderToUse,this.session.getSessionLog());
              if (metadataProperties != null && !metadataProperties.isEmpty()) {
                translateOldProperties(metadataProperties,this.session);
                deployProperties=mergeMaps(metadataProperties,deployProperties);
              }
            }
            this.processor.setClassLoader(classLoaderToUse);
            this.processor.createDynamicClasses();
            if (classLoaderToUse instanceof DynamicClassLoader) {
              this.processor.createRestInterfaces();
            }
            this.processor.addEntityListeners();
            if (this.projectCacheAccessor != null) {
              this.projectCacheAccessor.storeProject(this.session.getProject(),deployProperties,this.session.getSessionLog());
            }
            this.session.getProject().convertClassNamesToClasses(classLoaderToUse);
            if (!isCompositeMember()) {
              addBeanValidationListeners(deployProperties,classLoaderToUse);
            }
            this.processor.processCustomizers();
          }
          this.processor=null;
        }
 else {
          this.session.getProject().convertClassNamesToClasses(classLoaderToUse);
          if (!this.shouldBuildProject) {
            if (!isCompositeMember()) {
              addBeanValidationListeners(deployProperties,classLoaderToUse);
            }
            processDescriptorsFromCachedProject(classLoaderToUse);
          }
        }
        finishProcessingDescriptorEvents(classLoaderToUse);
        this.structConverters=getStructConverters(classLoaderToUse);
        updateRemote(deployProperties,classLoaderToUse);
        initSession();
        if (this.session.getIntegrityChecker().hasErrors()) {
          this.session.handleException(new IntegrityException(session.getIntegrityChecker()));
        }
        this.session.getDatasourcePlatform().getConversionManager().setLoader(classLoaderToUse);
        this.state=STATE_HALF_DEPLOYED;
      }
 else {
        this.deployLock.release();
        isLockAcquired=false;
        if (this.state == STATE_DEPLOY_FAILED) {
          throw persistenceException;
        }
      }
    }
    if (!isCompositeMember()) {
      if (this.session.isDatabaseSession() && !((DatabaseSessionImpl)session).isLoggedIn()) {
        if (!isLockAcquired) {
          this.deployLock.acquire();
          isLockAcquired=true;
        }
        if (!((DatabaseSessionImpl)this.session).isLoggedIn()) {
          if (this.state == STATE_DEPLOY_FAILED) {
            throw persistenceException;
          }
          this.session.setProperties(deployProperties);
          updateSession(deployProperties,classLoaderToUse);
          if (isValidationOnly(deployProperties,false)) {
            if (this.state == STATE_HALF_DEPLOYED) {
              getDatabaseSession().initializeDescriptors();
              this.state=STATE_DEPLOYED;
            }
          }
 else {
            try {
              updateTunerDeploy(deployProperties,classLoaderToUse);
              updateFreeMemory(deployProperties);
              if (this.isSessionLoadedFromSessionsXML) {
                getDatabaseSession().login();
              }
 else {
                login(getDatabaseSession(),deployProperties,requiresConnection);
              }
              DatabasePlatform platform=getDatabaseSession().getPlatform();
              PropertiesUtils.set(platform,PersistenceUnitProperties.TARGET_DATABASE_PROPERTIES,(String)deployProperties.get(PersistenceUnitProperties.TARGET_DATABASE_PROPERTIES));
              if (this.session.hasExternalTransactionController()) {
                if (this.session.getExternalTransactionController().getExceptionHandler() == null) {
                  this.session.getExternalTransactionController().setExceptionHandler(new ExceptionHandler(){
                    public Object handleException(                    RuntimeException exception){
                      if (exception instanceof org.eclipse.persistence.exceptions.OptimisticLockException) {
                        throw new OptimisticLockException(exception);
                      }
 else                       if (exception instanceof EclipseLinkException) {
                        throw new PersistenceException(exception);
                      }
 else {
                        throw exception;
                      }
                    }
                  }
);
                }
              }
              this.state=STATE_DEPLOYED;
            }
 catch (            Throwable loginException) {
              if (this.state == STATE_HALF_DEPLOYED) {
                if (this.session.isConnected()) {
                  try {
                    getDatabaseSession().logout();
                  }
 catch (                  Throwable logoutException) {
                  }
                  this.state=STATE_DEPLOY_FAILED;
                }
              }
              throw loginException;
            }
            if (!this.isSessionLoadedFromSessionsXML) {
              addStructConverters();
            }
            writeDDL(deployProperties,getDatabaseSession(deployProperties),classLoaderToUse);
          }
        }
        updateTunerPostDeploy(deployProperties,classLoaderToUse);
        this.deployLock.release();
        isLockAcquired=false;
      }
      try {
        this.getMetamodel(classLoaderToUse);
      }
 catch (      Exception e) {
        this.session.log(SessionLog.FINEST,SessionLog.METAMODEL,"String_Node_Str",new Object[]{e.getMessage()});
      }
    }
    if (this.weaver != null) {
      this.weaver.clear();
      this.weaver=null;
    }
    return this.session;
  }
 catch (  Throwable exception) {
    if (this.state == STATE_PREDEPLOYED) {
      this.state=STATE_DEPLOY_FAILED;
    }
    PersistenceException persistenceEx;
    if (this.state == STATE_DEPLOY_FAILED) {
      if (exception == persistenceException) {
        persistenceEx=new PersistenceException(EntityManagerSetupException.cannotDeployWithoutPredeploy(this.persistenceUnitInfo.getPersistenceUnitName(),this.state,this.persistenceException));
      }
 else {
        persistenceEx=createDeployFailedPersistenceException(exception);
      }
    }
 else {
      if (exception instanceof PersistenceException) {
        persistenceEx=(PersistenceException)exception;
      }
 else {
        persistenceEx=new PersistenceException(exception);
      }
    }
    if (isLockAcquired) {
      this.deployLock.release();
    }
    this.session.logThrowable(SessionLog.SEVERE,SessionLog.EJB,exception);
    throw persistenceEx;
  }
 finally {
    this.session.log(SessionLog.FINEST,SessionLog.JPA,"String_Node_Str",new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(),this.session.getName(),this.state,this.factoryCount});
  }
}

Fixed version (ground truth):
/** 
 * Deploy a persistence session and return an EntityManagerFactory. Deployment takes a session that was partially created in the predeploy call and makes it whole. This means doing any configuration that requires the real class definitions for the entities.  In the predeploy phase we were in a stage where we were not let allowed to load the real classes. Deploy could be called several times - but only the first call does the actual deploying - additional calls allow to update session properties (in case the session is not connected). Note that there is no need to synchronize deploy method - it doesn't alter factoryCount and while deploy is executed no other method can alter the current state (predeploy call would just increment factoryCount; undeploy call would not drop factoryCount to 0). However precautions should be taken to handle concurrent calls to deploy, because those may alter the current state or connect the session.
 * @param realClassLoader The class loader that was used to load the entity classes. This loaderwill be maintained for the lifespan of the loaded classes.
 * @param additionalProperties added to persistence unit properties for updateServerSession overriding existing properties.In JSE case it allows to alter properties in main (as opposed to preMain where preDeploy is called).
 * @return An EntityManagerFactory to be used by the Container to obtain EntityManagers
 */
public AbstractSession deploy(ClassLoader realClassLoader,Map additionalProperties){
  if (this.state != STATE_PREDEPLOYED && this.state != STATE_DEPLOYED && this.state != STATE_HALF_DEPLOYED) {
    if (mustBeCompositeMember()) {
      throw new PersistenceException(EntityManagerSetupException.compositeMemberCannotBeUsedStandalone(this.persistenceUnitInfo.getPersistenceUnitName()));
    }
    throw new PersistenceException(EntityManagerSetupException.cannotDeployWithoutPredeploy(this.persistenceUnitInfo.getPersistenceUnitName(),this.state,this.persistenceException));
  }
  this.session.log(SessionLog.FINEST,SessionLog.JPA,"String_Node_Str",new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(),this.session.getName(),this.state,this.factoryCount});
  ClassLoader classLoaderToUse=realClassLoader;
  if (additionalProperties.containsKey(PersistenceUnitProperties.CLASSLOADER)) {
    classLoaderToUse=(ClassLoader)additionalProperties.get(PersistenceUnitProperties.CLASSLOADER);
  }
 else   if ((this.processor != null) && (this.processor.getProject() != null) && (this.processor.getProject().hasVirtualClasses())&& (this.state == STATE_PREDEPLOYED)&& (!(classLoaderToUse instanceof DynamicClassLoader))) {
    classLoaderToUse=new DynamicClassLoader(classLoaderToUse);
  }
  boolean isLockAcquired=false;
  try {
    Map deployProperties=mergeMaps(additionalProperties,this.persistenceUnitInfo.getProperties());
    updateTunerPreDeploy(deployProperties,classLoaderToUse);
    translateOldProperties(deployProperties,this.session);
    if (isComposite()) {
      updateCompositeMembersProperties(deployProperties);
    }
    if (this.state == STATE_PREDEPLOYED) {
      this.deployLock.acquire();
      isLockAcquired=true;
      if (this.state == STATE_PREDEPLOYED) {
        if (this.shouldBuildProject && !this.isSessionLoadedFromSessionsXML) {
          if (isComposite()) {
            deployCompositeMembers(deployProperties,classLoaderToUse);
          }
 else {
            if (this.processor.getMetadataSource() != null) {
              Map metadataProperties=this.processor.getMetadataSource().getPropertyOverrides(deployProperties,classLoaderToUse,this.session.getSessionLog());
              if (metadataProperties != null && !metadataProperties.isEmpty()) {
                translateOldProperties(metadataProperties,this.session);
                deployProperties=mergeMaps(metadataProperties,deployProperties);
              }
            }
            this.processor.setClassLoader(classLoaderToUse);
            this.processor.createDynamicClasses();
            if (classLoaderToUse instanceof DynamicClassLoader) {
              this.processor.createRestInterfaces();
            }
            this.processor.addEntityListeners();
            if (this.projectCacheAccessor != null) {
              this.projectCacheAccessor.storeProject(this.session.getProject(),deployProperties,this.session.getSessionLog());
            }
            this.session.getProject().convertClassNamesToClasses(classLoaderToUse);
            if (!isCompositeMember()) {
              addBeanValidationListeners(deployProperties,classLoaderToUse);
            }
            this.processor.processCustomizers();
          }
          this.processor=null;
        }
 else {
          this.session.getProject().convertClassNamesToClasses(classLoaderToUse);
          if (!this.shouldBuildProject) {
            if (!isCompositeMember()) {
              addBeanValidationListeners(deployProperties,classLoaderToUse);
            }
            processDescriptorsFromCachedProject(classLoaderToUse);
          }
        }
        finishProcessingDescriptorEvents(classLoaderToUse);
        this.structConverters=getStructConverters(classLoaderToUse);
        updateRemote(deployProperties,classLoaderToUse);
        initSession();
        if (this.session.getIntegrityChecker().hasErrors()) {
          this.session.handleException(new IntegrityException(session.getIntegrityChecker()));
        }
        this.session.getDatasourcePlatform().getConversionManager().setLoader(classLoaderToUse);
        this.state=STATE_HALF_DEPLOYED;
      }
 else {
        this.deployLock.release();
        isLockAcquired=false;
        if (this.state == STATE_DEPLOY_FAILED) {
          throw persistenceException;
        }
      }
    }
    if (!isCompositeMember()) {
      if (this.session.isDatabaseSession() && !((DatabaseSessionImpl)session).isLoggedIn()) {
        if (!isLockAcquired) {
          this.deployLock.acquire();
          isLockAcquired=true;
        }
        if (!((DatabaseSessionImpl)this.session).isLoggedIn()) {
          if (this.state == STATE_DEPLOY_FAILED) {
            throw persistenceException;
          }
          this.session.setProperties(deployProperties);
          updateSession(deployProperties,classLoaderToUse);
          if (isValidationOnly(deployProperties,false)) {
            if (this.state == STATE_HALF_DEPLOYED) {
              getDatabaseSession().initializeDescriptors();
              this.state=STATE_DEPLOYED;
            }
          }
 else {
            try {
              updateTunerDeploy(deployProperties,classLoaderToUse);
              updateFreeMemory(deployProperties);
              if (this.isSessionLoadedFromSessionsXML) {
                getDatabaseSession().login();
              }
 else {
                login(getDatabaseSession(),deployProperties,requiresConnection);
              }
              final Platform platform=getDatabaseSession().getDatasourcePlatform();
              PropertiesUtils.set(platform,PersistenceUnitProperties.TARGET_DATABASE_PROPERTIES,(String)deployProperties.get(PersistenceUnitProperties.TARGET_DATABASE_PROPERTIES));
              if (this.session.hasExternalTransactionController()) {
                if (this.session.getExternalTransactionController().getExceptionHandler() == null) {
                  this.session.getExternalTransactionController().setExceptionHandler(new ExceptionHandler(){
                    public Object handleException(                    RuntimeException exception){
                      if (exception instanceof org.eclipse.persistence.exceptions.OptimisticLockException) {
                        throw new OptimisticLockException(exception);
                      }
 else                       if (exception instanceof EclipseLinkException) {
                        throw new PersistenceException(exception);
                      }
 else {
                        throw exception;
                      }
                    }
                  }
);
                }
              }
              this.state=STATE_DEPLOYED;
            }
 catch (            Throwable loginException) {
              if (this.state == STATE_HALF_DEPLOYED) {
                if (this.session.isConnected()) {
                  try {
                    getDatabaseSession().logout();
                  }
 catch (                  Throwable logoutException) {
                  }
                  this.state=STATE_DEPLOY_FAILED;
                }
              }
              throw loginException;
            }
            if (!this.isSessionLoadedFromSessionsXML) {
              addStructConverters();
            }
            writeDDL(deployProperties,getDatabaseSession(deployProperties),classLoaderToUse);
          }
        }
        updateTunerPostDeploy(deployProperties,classLoaderToUse);
        this.deployLock.release();
        isLockAcquired=false;
      }
      try {
        this.getMetamodel(classLoaderToUse);
      }
 catch (      Exception e) {
        this.session.log(SessionLog.FINEST,SessionLog.METAMODEL,"String_Node_Str",new Object[]{e.getMessage()});
      }
    }
    if (this.weaver != null) {
      this.weaver.clear();
      this.weaver=null;
    }
    return this.session;
  }
 catch (  Throwable exception) {
    if (this.state == STATE_PREDEPLOYED) {
      this.state=STATE_DEPLOY_FAILED;
    }
    PersistenceException persistenceEx;
    if (this.state == STATE_DEPLOY_FAILED) {
      if (exception == persistenceException) {
        persistenceEx=new PersistenceException(EntityManagerSetupException.cannotDeployWithoutPredeploy(this.persistenceUnitInfo.getPersistenceUnitName(),this.state,this.persistenceException));
      }
 else {
        persistenceEx=createDeployFailedPersistenceException(exception);
      }
    }
 else {
      if (exception instanceof PersistenceException) {
        persistenceEx=(PersistenceException)exception;
      }
 else {
        persistenceEx=new PersistenceException(exception);
      }
    }
    if (isLockAcquired) {
      this.deployLock.release();
    }
    this.session.logThrowable(SessionLog.SEVERE,SessionLog.EJB,exception);
    throw persistenceEx;
  }
 finally {
    this.session.log(SessionLog.FINEST,SessionLog.JPA,"String_Node_Str",new Object[]{getPersistenceUnitInfo().getPersistenceUnitName(),this.session.getName(),this.state,this.factoryCount});
  }
}