[BUGFIX] ClassLoader: Clear after Exception 62/34162/2
authorAlexander Opitz <opitz.alexander@googlemail.com>
Fri, 26 Sep 2014 07:55:13 +0000 (09:55 +0200)
committerBenjamin Mack <benni@typo3.org>
Fri, 14 Nov 2014 14:46:19 +0000 (15:46 +0100)
Clearing the class cache and release the lock if an exception was
thrown while generating the class loader cache.

Resolves: #61900
Releases: master, 6.2
Change-Id: Iaac534e9cf333fe29f9ac90aed118cc953f857fe
Reviewed-on: http://review.typo3.org/34162
Reviewed-by: Oliver Hader <oliver.hader@typo3.org>
Tested-by: Oliver Hader <oliver.hader@typo3.org>
typo3/sysext/core/Classes/Core/ClassLoader.php

index 868835d..afb5f7e 100644 (file)
@@ -487,17 +487,25 @@ class ClassLoader {
 
                // Take a look again, after lock is acquired
                if (!$this->loadPackageNamespacesFromCache()) {
-                       foreach ($this->packages as $package) {
-                               $this->buildPackageNamespaceAndClassesPath($package);
+                       try {
+                               foreach ($this->packages as $package) {
+                                       $this->buildPackageNamespaceAndClassesPath($package);
+                               }
+                               $this->sortPackageNamespaces();
+                               $this->savePackageNamespacesAndClassesPathsToCache();
+                               // The class alias map has to be rebuilt first, because ext_autoload files can contain
+                               // old class names that need established class aliases.
+                               $classNameToAliasMapping = $this->classAliasMap->setPackages($this->packages)->buildMappingAndInitializeEarlyInstanceMapping();
+                               $this->loadClassFilesFromAutoloadRegistryIntoRuntimeClassInformationCache($this->packages);
+                               $this->classAliasMap->buildMappingFiles($classNameToAliasMapping);
+                               $this->transferRuntimeClassInformationCacheEntriesToClassesCache();
+                       } catch (\Exception $e) {
+                               // Catching all Exceptions, as we don't know where in the process the class cache building breaks we
+                               // need to clear our cache and also release our lock before we throw the Exception again to the user.
+                               $this->clearClassesCache();
+                               $this->releaseLock($didLock);
+                               throw $e;
                        }
-                       $this->sortPackageNamespaces();
-                       $this->savePackageNamespacesAndClassesPathsToCache();
-                       // The class alias map has to be rebuilt first, because ext_autoload files can contain
-                       // old class names that need established class aliases.
-                       $classNameToAliasMapping = $this->classAliasMap->setPackages($this->packages)->buildMappingAndInitializeEarlyInstanceMapping();
-                       $this->loadClassFilesFromAutoloadRegistryIntoRuntimeClassInformationCache($this->packages);
-                       $this->classAliasMap->buildMappingFiles($classNameToAliasMapping);
-                       $this->transferRuntimeClassInformationCacheEntriesToClassesCache();
                }
 
                $this->releaseLock($didLock);
@@ -625,6 +633,16 @@ class ClassLoader {
        }
 
        /**
+        * Cleares the complete cache for class loader.
+        *
+        * @return void
+        */
+       protected function clearClassesCache() {
+               $this->coreCache->flush();
+               $this->classesCache->flush();
+       }
+
+       /**
         * Sorts longer package namespaces first, to find specific matches before generic ones
         *
         * @return void