Open swis opened 11 years ago
I guess it's related to symfony/symfony#7360.
+1
Could someone reproduce this on a fresh fork of the symfony-standard edition version 2.1?
When I have controller action with @secure annotation and I'm trying to clear cache for prod env (cache folder is empty - no files inside) this exception appears.
I just tried upgrading again, from Symfony 2.1.8 to 2.1.9, but this error is still present using
Would be nice to have this fixed soon.
same here. It was giving an error since several days ago. I've added "minimum-stability": "dev" and now works. So maybe it's fixed.
symfony (2.1.9)
jms/di-extra-bundle (1.1.1)
jms/security-extra-bundle (1.2.0)
I tried again using the following sets with Symfony 2.1.9:
- jms/aop-bundle (1.0.0)
- jms/cg (1.0.0)
- jms/di-extra-bundle (1.1.1)
- jms/metadata (1.1.1)
- jms/security-extra-bundle (1.2.0)
- jms/aop-bundle (dev-master 7018357)
- jms/cg (dev-master 75a519d)
- jms/di-extra-bundle (dev-master a153677)
- jms/metadata (dev-master f2ab788)
- jms/parser-lib (dev-master 4d469a7)
- jms/security-extra-bundle (dev-master f2a345d)
Both don't work.
Christian, are you using Twig? I've just found out that if I do:
php app/console cache:clear --env=prod
if I have loaded Twig in AppKernel I have this error:
PHP Fatal error: Allowed memory size of 536870912 bytes exhausted (tried to allocate 130968 bytes) in /vendor/symfony/symfony/src/Symfony/Component/DependencyInjection/Compiler/AnalyzeServiceReferencesPass.php on line 97
if I haven't loaded Twig then I have the redeclare error:
PHP Fatal error: Cannot redeclare class
EnhancedProxy_5f83e70703f016ed810ebb73fecd0ecb3bdf2351\__CG__\TE\ApiBundle\Controller\FlagController in .../app/cache/pro_/jms_diextra/proxies/TE-ApiBundle-Controller-FlagController.php on line 46
Totally blocked right now :S.
@fesja: Yes, I'm using Twig. But I don't think that it has to do with this issue directly. I have no idea which component is causing it, though.
@schmittjoh: Can you reproduce it?
@craue you'll see the root cause of this bug in the PR link above. I think the fix is on Sf2 side.
It happens in my case is that if I do:
...
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\HttpFoundation\Request;
use JMS\SecurityExtraBundle\Annotation\Secure;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
/**
*
*/
class OrganizationController extends Controller
{
/**
* @Route("/organizations/new")
* @Method({"GET","POST"})
* @Secure(roles="ROLE_ORG_ADMIN")
*/
public function newAction(Request $request)
{
instead of
...
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Symfony\Component\HttpFoundation\Request;
use JMS\SecurityExtraBundle\Annotation\Secure;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
/**
*
*/
class OrganizationController extends Controller
{
/**
* @Route("/organizations/new")
* @Method({"GET","POST"})
* @Secure(roles="ROLE_ORG_ADMIN")
*/
public function newAction(Request $request)
{
It works !
See the different ? there is an extra return between this line
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
and the comment block
/**
*
*/
class OrganizationController extends Controller
In my case, @PreAuthorize
seems to cause this issue. If I remove them from all controllers, the error doesn't show up.
@schmittjoh: Here's how to trigger this error with a clean 2.1.9 standard edition: In src/Acme/DemoBundle/Controller/SecuredController.php
, change
/**
* @Route("/hello/admin/{name}", name="_demo_secured_hello_admin")
* @Secure(roles="ROLE_ADMIN")
* @Template()
*/
public function helloadminAction($name)
{
return array('name' => $name);
}
from
public function helloadminAction($name)
{
to
public function helloadminAction($name) {
and try clearing the cache with php app\console ca:cl
.
What is the status of this ticket?
Any updates to this?
I just stumbled into this bug when upgrading to 2.3 but then even downgrading to 2.2 results in the same error. No fix for this yet?
I discovered if I remove the cache folder manually (rm -Rf) and then visit a URL with a controller using a JMS bundle (in this case, the JMS Security for a @Secure annotation) everything works as expected, in this case, if I go and do a cache:clear I get no errors (with or without warmup).
A bit annoying but at least that works.
+1 Meet error on tests at first run after clearing the cache. It`s a Heisenbug, possible that it rise only with >= 2 environments at empty cache. Trying to reproduce it on fresh fork.
+1 here, Exact same error when trying to cache:clear. I've upgraded from 2.2 to 2.3 too.
+1
MacOS without APC:
git clone git@github.com:symfony/symfony-standard.git
cd symfony-standard
git checkout v2.2.3
composer.phar install
app/console cache:clear -e test
Running cache:clear a second time works unless cache doesn't exist, e.g.,
rm -rf app/cache/*
app/console cache:clear -e test
This code seems related (in JMS\DiExtraBundle\HttpKernel\ControllerInjectorsWarmer
):
public function warmUp($cacheDir)
{
// This avoids class-being-declared twice errors when the cache:clear
// command is called. The controllers are not pre-generated in that case.
$suffix = defined('Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerAggregate::NEW_CACHE_FOLDER_SUFFIX')
? CacheWarmerAggregate::NEW_CACHE_FOLDER_SUFFIX
: '_new';
if (basename($cacheDir) === $this->kernel->getEnvironment().$suffix) {
return;
}
$classes = $this->findControllerClasses();
foreach ($classes as $class) {
$this->controllerResolver->createInjector($class);
}
}
This probably needs to be adjusted to detect the 2.3 way of naming the temporary cache directory (dev
becomes de_
instead of dev_new
).
EDIT: Tested and working with this replacement code:
public function warmUp($cacheDir)
{
// This avoids class-being-declared twice errors when the cache:clear
// command is called. The controllers are not pre-generated in that case.
if (basename($cacheDir) === preg_replace('#.$#', '_', $this->kernel->getEnvironment())) {
return;
}
$classes = $this->findControllerClasses();
foreach ($classes as $class) {
$this->controllerResolver->createInjector($class);
}
}
Unfortunately, the workaround from @tomat doesn't work for me in symfony 2.3 :/
Yeah, just noticed that this bug was older than Symfony 2.3, but my PR will solve it for some users at least.
@swis: Do you have an updated composer.json
for your project? I'm getting "could not be resolved to an installable set of packages" on the one you posted 4 months ago.
Same problem found in symfony 2.1.11.
PHP Fatal error: Cannot redeclare class EnhancedProxyed2f3cb92db5d961490e60a593d20b156b460b0dCG\MV\CaravanBundle\Controller\AdminLogController in app/cache/pro/jms_diextra/proxies/MV-CaravanBundle-Controller-AdminLogController.php on line 37
@tomat: Here you go: https://gist.github.com/swis/5941281 (Although it's in the file: Obviously it's not the symfony standard edition)
EDIT: I'm going to try the commits of @robocoder asap in my setup at sf2.3
EDIT2: I just saw, that the contributed composer.json may be kinda useless, since the is no version information. The installed versions are:
jms/aop-bundle: 1.0.0,
jms/cg: 1.0.0,
jms/di-extra-bundle: 1.4.0,
jms/i18n-routing-bundle: 1.1.0,
jms/metadata: 1.3.0,
jms/parser-lib: 1.0.0,
jms/security-extra-bundle: 1.5.1,
jms/serializer: 0.12.0,
jms/serializer-bundle: dev-master (66d2fe197bacb82f7b476099144f03596719b24d),
jms/translation-bundle: 1.1.0
The fix from @tomat is working for me symfony 2.2.3
I'm using:
"jms/security-extra-bundle": "1.5.*",
"jms/di-extra-bundle": "1.4.*",
Unfortunately, 3daedc9 by @robocoder still does not fix the error for my forementioned setup:
Cannot redeclare class EnhancedProxy_73b88e6bf5989f9e4785cea753cad509a15376f1\__CG__\JMS\SecurityExtraBundle\Tests\Functional\TestBundle\Controller\PostController in /my/project/app/cache/backend_test/jms_diextra/lookup_method_classes/JMS-SecurityExtraBundle-Tests-Functional-TestBundle-Controller-PostController.php on line 11
But 22e8d41 seems to fix the issue .. I couldn't reproduce the error so far. I will give some further feedback in a few days.
Edit: GNAH! 22e8d41 doesn't fix the issue.
Okay guys, I'll leave here.
Since we're planning to go live in August, I have no time to invest so much (more) time in this issue. I've written my own @Secure annotation (this is the only one I need from the bundle). If someone is interested in the code, please write me a message.
Don't use 22e8d41 ... It's rubbish. I'm not surprised 3daedc9 doesn't work for some since it only guards the kernel loading twice, ie there's probably another edge case.
Given the fragility of the cache warming system, I think the only viable solution moving forward is to convert the current cache warmer (HttpFoundation\ControllerCacheWarmer) class to a separate command which needs to be invoked manually during deployment.
If someone has time to work on this (it should be fairly simple), please let me know or better yet, send a PR right away :)
Reproduce this bug on clear symfony-standard. @schmittjoh Please try it, maybe it will help you detect problem
"jms/security-extra-bundle": "1.5.*",
"jms/di-extra-bundle": "1.4.*"
clone https://github.com/i4got10/symfony-standard.git && checkout issue96
run rm -r app/cache && phpunit -c app
Its seems that re-enabling the APC for the PHP-CLI fixes the problem for me... wired :|
apc.enable_cli=on/off gives the same result here.
@i4got10: Successfully reproduced and fixed, not sure if this breaks other stuff though, so please test it before I make a PR.
Fix is in https://github.com/tomat/JMSDiExtraBundle/commit/59eafd96707873d8001e01a97eadd8c66ca38bcc
Also forked @i4got10:s symfony-standard so that it uses my fix: https://github.com/tomat/symfony-standard/tree/patch-1 (git clone, git checkout patch-1, composer install, rm -r app/cache && phpunit -c app)
Edit: Forgot to update composer.lock ;-)
@tomat nice one. Solve my problem with 2 test environments. Also work with
"jms/security-extra-bundle": "1.4.*",
"jms/di-extra-bundle": "1.3.*",
Hi everyone, another guy annoyed by this "cannot redeclare class" error here !
I tryied the differents workaround and patches here but none fully solved the problem so I digged into sf and jms code to try to understand what happens and i think i found the root but no fix for now ...
Following the workflow of the cache:clear command, here is what happens in case 2:
Symfony\Bundle\FrameworkBundle\Console\Application::registerCommands
boots the kernel to register the commands from all bundlesInjector
s classes in the _controllerinjectors cache folderHere we go ! The class is loaded for the first time
The cache is then cleared and warmed up again by the command but in a temporary directory (de_ for dev) so when the DefinitionInjectorGenerator
make a require_once again, it is not the same file so it is evaluated, but the class inside is the same and so the error is raised.
In the ControllerInjectorWarmer there is a condition based on the directory beiing warmed to determine if the warming up is actualy done. There is a comment in the code saying :
This avoids class-being-declared twice errors when the cache:clear command is called. The controllers are not pre-generated in that case.
In the case of the cache:clear command as described above, the warming up is done at first on the dev
folder and then on the de_
folder (which will be renamed as dev later)
So we can prevent the first warmup with a condition like
if (basename($cacheDir) !== basename(substr($this->kernel->getCacheDir(), 0, -1).'_'))
the error goes away and the proxy files are created in dev
But another issue raises !! If you reload a page in your browser after modifying your controller, the cache is not updated anymore because in that case the warmup is done on the dev folder, which was excluded with the previous condition
So in one case we want warmup to be done for de_ and not dev, in the other case we want it to be done for dev
The "cannot redeclare class" error can also happen in a different situtation : when you reload a page from a controller using jms capabilities (when the controller is declared as a service)
The same pattern applies here:
DefinitionInjectorGenerator
ControllerResolver
asks the container for the controller service, which calls a method like getMy_Toto_ControllerService() on the MyDevDebugProjectContainer.php
I think one solution would be to provide an autoloader for all the jms-generated classes (i think doctrine does this for the entity proxies) and then avoid the problematic require statements.
Any tought or help on this one would be greatly appreciated as it is really messing in the developpement workflow (even if non blocking for production)
Seems to be solved by #117 on Symfony 2.3.4 (2.3.x I guess)
It fixes the probleme with the cache:clear command but not when reloading a page from browser (after modifying its controller)
In fact it does not solve the problem as the warmup is not done anymore during the command, the injectors are not created !
Upgrading Symfony to 2.3.4
I have the same issue again:
Cannot redeclare class EnhancedProxy_...
+1
+1
+1
+1
@i4got10 Could not test #131 with the cache:clear command as it is broken in my project now but it does not solve the issue when refreshing a page
@vkhramtsov : same thing
I'm having this issue as well with Symfony 2.3. Could it be as I use my controller as a service?
The bad part with this bug is that
1) there's no fix for last 3 subversions / last 8 months 2) most of the JMS bundles that use DI/AOP/CG, like Translation, a.s.o. are useless; if I take them out everything works smooth 3) does not work on neither Symf 2.1/2.2 or any other combination of versions.
After more than 12 hours I stumbled on same issues as listed before. I see no option now than leaving all these bundles behind and probably get back and contribute with ideas if by that time it won't be fixed.
I was already wondering why I'd need 3 bundles just to be able to add an @Secure to my action... Some other things I've noticed while developing with this bundle:
@CristianSitov in our project the bundles causes issues in dev environnement and cache clearing but it has no impact in our production, everything works fine and as expected, maybe you don't have to leave the bundles ...
@iltar That's called decoupling ! yes you need several bundle for the @secure annotation but you may not need the whole security bundle if you're only looking at AOP capabilities, etc ... the "hard" refresh or "smooth" refresh makes no difference server side (it's only a matter of browser caching)
I just added some ACL stuff to my project and now, when clearing the cache with
immediately I got the following error:
I already tried different versions of Symfony and DiExtraBundle (and different combinations), but the error remains even when I downgrade Symfony to 2.1. I don't know, but I suppose, this is somehow related to #95 - especially because of this CacheWarmer issue in the Stack. But I'm pretty sure, to not compile any Controller manually. Here's my current composer.json:
I'm looking for a workaround, since clearing the cache manually by removing the files is not appropriate in my case (especially for the CI stuff).
It may be of note that I'm using
@SecureParam
as well as@Secure
annotations (the error occurs even if I use only one of them in the BackendController).