framework
framework copied to clipboard
Uncaught Error: Class 'Doctrine\Common\Annotations\AnnotationReader' not found
Hello, I'm trying to use Go in a project, but it's crashing out of the box. It seems strange to me because I would think a crash this basic would affect more people. Perhaps it's my environment. I added some print debugging to the composer ClassLoader and the AopComposerLoader. As you can see it successfully locates the files on disk and includes them, but in the case of the doctrine AnnotationReader it tries to apply the go.source.transforming.loader filter and crashes the program.
Searching for class Symfony\Component\Console\Application with extension .php File path before rewrite: /root/git/project/vendor/composer/../symfony/console/Application.php File path after rewrite: php://filter/read=go.source.transforming.loader/resource=/root/git/project/vendor/composer/../symfony/console/Application.php Searching for class Go\Instrument\Transformer\StreamMetaData with extension .php File path before rewrite: /root/git/project/vendor/composer/../goaop/framework/src/Instrument/Transformer/StreamMetaData.php File path after rewrite: /root/git/project/vendor/composer/../goaop/framework/src/Instrument/Transformer/StreamMetaData.php Including /root/git/project/vendor/composer/../goaop/framework/src/Instrument/Transformer/StreamMetaData.php Searching for class Go\Instrument\Transformer\WeavingTransformer with extension .php File path before rewrite: /root/git/project/vendor/composer/../goaop/framework/src/Instrument/Transformer/WeavingTransformer.php File path after rewrite: /root/git/project/vendor/composer/../goaop/framework/src/Instrument/Transformer/WeavingTransformer.php Including /root/git/project/vendor/composer/../goaop/framework/src/Instrument/Transformer/WeavingTransformer.php Searching for class Go\Core\AdviceMatcher with extension .php File path before rewrite: /root/git/project/vendor/composer/../goaop/framework/src/Core/AdviceMatcher.php File path after rewrite: /root/git/project/vendor/composer/../goaop/framework/src/Core/AdviceMatcher.php Including /root/git/project/vendor/composer/../goaop/framework/src/Core/AdviceMatcher.php Searching for class Go\Core\AspectLoader with extension .php File path before rewrite: /root/git/project/vendor/composer/../goaop/framework/src/Core/AspectLoader.php File path after rewrite: /root/git/project/vendor/composer/../goaop/framework/src/Core/AspectLoader.php Including /root/git/project/vendor/composer/../goaop/framework/src/Core/AspectLoader.php Searching for class Doctrine\Common\Annotations\AnnotationReader with extension .php File path before rewrite: /root/git/project/vendor/composer/../doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationReader.php File path after rewrite: php://filter/read=go.source.transforming.loader/resource=/root/git/project/vendor/composer/../doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationReader.php PHP Fatal error: Uncaught Error: Class 'Doctrine\Common\Annotations\AnnotationReader' not found in /root/git/project/vendor/goaop/framework/src/Core/GoAspectContainer.php:88 Stack trace: #0 /root/git/project/vendor/goaop/framework/src/Core/Container.php(65): Go\Core\GoAspectContainer->Go\Core{closure}(Object(Go\Core\GoAspectContainer)) #1 /root/git/project/vendor/goaop/framework/src/Core/Container.php(87): Go\Core\Container->Go\Core{closure}(Object(Go\Core\GoAspectContainer)) #2 /root/git/project/vendor/goaop/framework/src/Core/GoAspectContainer.php(50): Go\Core\Container->get('aspect.annotati...') #3 /root/git/project/vendor/goaop/framework/src/Core/Container.php(65): Go\Core\GoAspectContainer->Go\Core{closure}(Object(Go\Core\GoAspectContainer)) #4 /root/git/project/vendor/goaop/framework/src/Core/Container.php(87): Go\Core\Container->Go\Core{closure}(Object(Go\Core\GoAspectContainer)) #5 /root/git/project/vendor/goaop/framework/src/Core/GoAspectContai in /root/git/project/vendor/goaop/framework/src/Core/GoAspectContainer.php on line 88
Hi, I have an idea that this is due to the composer update. Could you please, show me an information about:
- Version of PHP
- Version of goaop/framework
- Version of composer
Hello. This is all from the machine I'm testing on. I'm running 16.04 server if that makes a difference.
php --version
PHP 7.0.4-7ubuntu2.1 (cli) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
with Zend OPcache v7.0.6-dev, Copyright (c) 1999-2016, by Zend Technologies
cat composer.json | grep goaop
"goaop/framework": "2.0.0"
I had the version set to "*", but I tried "2.0.0" as a debugging step. Didn't seem to make a difference.
composer --version
Composer version 1.1.2 2016-05-31 19:48:11
Could you also show me the config for initialization, especially appDir, includePaths and excludePaths for your app.
Maybe you just include vendor libraries too? Not only the src folder of your app? In this case AOP will try to intercept and analyze itself and will definitely crash. To solve this, just add vendor directory to the excludePaths option.
That was causing the crash. I had include paths set to ( ".." ). I didn't realize that was the issue because it was working perfectly for about three weeks before it started crashing. I gave a demo and everything. Strangeness.
Thanks for the help, and the framework!
You are welcome! )
I think that I should put a guard into the kernel that will throw an exception for this misconfiguration.
More setup documentation would be helpful. It's easy to get 90% of the way there but if the starting example doesn't work it's hard to get more information.
In some cases, we actually want to do AOP on dependencies resolved to the /vendor path (or other path that is configured). How would we go about preventing self initialization by default during the configuration phase?
Happy to commit to a PR as this improves integration stability. @lisachenko what do you think works best towards releasing a fix?
Hi, @RubieV!
In the case when you want to apply AOP to vendor libraries as well, you should mark all framework dependencies as excluded to prevent analysis. Sorry, that I haven't put this guard because of lack of time (I'm learning for driving license and planning my new flat, so no free time for my OSS pojects)
I will be happy to accept a PR that can automatically calculate (or ask the composer) for directories of dependencies and put them into the excludePaths option. One more hint: could you please make a PR related to the 1,x branch for cascade merge (or we can check this new github feature for PR :smiley: ).
This is a strange issue I am facing too. I am not sure if I understand the problem and how to fix it.
I just upgraded from 1.1.1 to 2.0.0 and now there is the error:
PHP Fatal error: Class 'Doctrine\Common\Annotations\AnnotationReader' not found in /var/www/xyz/vendor/goaop/framework/src/Core/GoAspectContainer.php on line 88
OK, issue nailed down.
https://github.com/goaop/framework/blob/master/src/Instrument/FileSystem/Enumerator.php#L109
It is checked if the current realpath is within an excludePath.
Now in my setup, the exludepaths contains "..", so the comparison does not match:
$realpath -> /var/www/xyz/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationReader.php $excludePath = /var/www/xyz/vendor/composer/../doctrine
So there is no match and AOP tries to rewrite. How to overcome? I don't know why the ComposerLoader Prefixes contain a relative part?
autoload_static.php in vendor/composer says:
public static $prefixesPsr0 = array (
'D' =>
array (
'Doctrine\\Common\\Lexer\\' =>
array (
0 => __DIR__ . '/..' . '/doctrine/lexer/lib',
),
'Doctrine\\Common\\Annotations\\' =>
array (
0 => __DIR__ . '/..' . '/doctrine/annotations/lib',
),
'Dissect' =>
array (
0 => __DIR__ . '/..' . '/jakubledl/dissect/src',
),
),
);
This is where it comes from. But why does it only affect me and not all others using GOAOP?
wow, if I fix the path-problem with using realpath($excludePath) then the next fatal error rises:
PHP Fatal error: Class 'PhpParser\Node\Name' not found
edit:
Wow, really seems like you need to exclude the whole vendor path like said before, but then there will be another error:
Class Mage_Core_Controller_Varien_Action was not found by locator
Trace:
#0 /var/www/xyz/vendor/goaop/parser-reflection/src/ReflectionEngine.php(124): Go\ParserReflection\ReflectionEngine::locateClassFile('Mage_Core_Contr...')
OK, now I got it. Had to implement my own Locator for this. But still got an issue, if the Locator can't resolve a specific classname - it still fails with "was not found by locator". Is there any way to avoid the exception? andrewsville/php-token-reflection did return a dummy class in this case.
$class = $broker->getClass('Nonexistent'); // returns a TokenReflection\Dummy\ReflectionClass instance
This is very annoying, upgrading from 1.x to 2.x is a pain....
Ok, I can overcome this problem by creating a dummy-file on runtime. But it seems like in 2.x it is not possible anymore to intercept non-namespaced classes anymore....or it is a problem of the new parser reflection library, which fails to find a namespace.
Namespace was not found in the file /var/www/xyz/htdocs/app/code/core/Mage/Core/Model/Translate.php
bye bye, aop framework. It was a joy - until 2.x appeared. :/
Hi, @infabo
Sorry for the inconvenience, I'm going to recheck each of your case, maybe on weekends or on my vacation. Unfortunately, I haven't free time right now, but I'm appreciate your time spending on debugging and reporting, so I'll definitely fix them all and report you in this task.
So you will know, that your work won't be lost. And hopefully, you will be able to return back to it with reliable behaviour.
Best regards, Alexander
This should be related to https://github.com/goaop/parser-reflection/issues/31
puh, after this long time it is even hard to follow my own debug-observations. Bug still there. :/
The original problem seems to be, that Doctrine Annotations lib switched to PSR-4 (was PSR-0) before. So the excludePath detection does not work anymore, because the code only fetches composer PSR-0 prefixes.
Wow, it seems like I have solved all the issues described by me above. Seems like the "thing" with "Namespace was not found in the file" is not an issue anymore. Works for now. Only drawback by now, v2.1.0 adds another ~200ms to my application time. Not clear what causing it, but since 1.x already had some runtime overhead - this is now beyond acceptable (maybe around 300-400ms extra). Not acceptable in my opinion.
Hi, @infabo. Thank you for constant reporting! Issues with namespace should be fixed in goaop/parser-reflection, so yes, confirming that several cases were fixed.
But let's check what going on with performance. 2.x branch uses AST-based reflection, so parsing can be slower. But if cache is already prepared and opcache is enabled then fast hit is expected. Only known overhead exists with class loading. Could you report how many classes are loaded in your application for your typical request?
I know one way with ever tighter integration with composer to completely exclude this overhead with class loading with hot cache. But it requires a lot of changes in the engine. So let's start with numbers and reasons why your application performance is suffered. Maybe you could create 2 XDebug profiles without AOP/with AOP for me to check this for you?
Is this issue still open?
i am surprised because "AnnotationReader" instance working vendor/goaop/framework/src/Core/GoAspectContainer.php constructor where as not working with anonymous (inside $this->share('aspect.annotation.reader', function(Container $container) {)
Hi, @shiva-050865
This issue is typically occurs when AOP framework tries to intercept it's own classes (you should check that vendor dir is excluded from processing). You can try to add vendor dir to the excludePaths option for the kernel.
Unfortunately, I tried to rewrite this part of code several times, but it's very tricky and I haven't succeeded yet. Maybe for v3.0 it will work without excluding framework's core libraries directories automatically.
@lisachenko Thank you for response..
But once I ignored vendor from AspectKernel getting following error.
Catchable fatal error: Argument 1 passed to TestMonitorAspect::beforeMethodExecution() must implement interface Go\Aop\Intercept\MethodInvocation, instance of Go\Aop\Framework\StaticInitializationJoinpoint given, called in /media/drive/bejgam.shiva/vendor/goaop/framework/src/Aop/Framework/BeforeInterceptor.php on line 33 and defined in /media/drive/bejgam.shiva/app/aspect/TestMonitorAspect.php on line 29
php Version: PHP 5.6.22-1
@shiva-050865 Ah, looks like you are using within type of joinpoint. This joinpoint will match not only with public, protected and static methods, but also with class initialization and property access.
You should add additional qualifier like this: within(bla-bla-bla) && execution(public **->*(*)) to filter only public method execution.
Or you can change typehint to the Joinpoint class and just echo this instance to see what was intercepted by the AOP engine.
@lisachenko Might be small question am not finding that how you are relating annotations with aspect.. am trying to create custom annotation with aspect. I just followed following article http://go.aopphp.com/blog/2013/07/21/implementing-logging-aspect-with-doctrine-annotations/
Am using yii2
No more relevant, as version 4 will use native PHP Attributes instead of Doctrine annotations.