-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Description
Versions:
- ide-helper Version: 3.6.1
- PHP Version: 8.4.16
Description:
During class fetch: Uncaught ReflectionException: Class 'Doctrine\Persistence\Mapping\StaticReflectionService' not found. in /opt/app/vendor/barryvdh/laravel-ide-helper/src/Console/MetaCommand.php:203
The MetaCommand creates a fatal error by registering an autoload function and throwing an exception if the class does not exist. This creates a problem if there is a valid use case where the existence of a class is optional and class_exists() is used to determine what implementation to use, for example to be able to use a new class if it exists, but keep (e.g. backwards) compatibility if it doesn't.
Though most users of Laravel will be using Eloquent models, we use Doctrine instead preferring an ORM based approach over Eloquent's Active Record pattern. We ran into the issue when upgrading ORM to version 3, which also upgraded doctrine/persistence to version 4. The doctrine/orm library has a check for the class StaticReflectionService. This class was removed from doctrine/persistence in version 4, but to keep doctrine/orm compatible with version 3.3+ they check for its existence to determine how to implement the GetReflectionClassImplementation trait.
Steps To Reproduce:
-
Start a clean docker container with PHP:
docker run --rm -it php:8.4-cli bash -l -
Execute the following to install Laravel, the IDE helper, and Doctrine ORM, and add a simple deferred service provider that provides an
EntityManager:
apt update && \
apt install -y --no-install-recommends git unzip && \
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin/ --filename=composer && \
composer create-project laravel/laravel /opt/app && \
cd /opt/app && \
composer require --dev barryvdh/laravel-ide-helper && \
composer require 'doctrine/orm:^3' 'symfony/cache:^7' 'symfony/var-exporter:^7' && \
php artisan make:provider DoctrineServiceProvider && \
cat > app/Providers/DoctrineServiceProvider.php <<'EOF'
<?php
namespace App\Providers;
use Doctrine\DBAL\DriverManager;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\ORMSetup;
use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Support\ServiceProvider;
class DoctrineServiceProvider extends ServiceProvider implements DeferrableProvider
{
public function register(): void
{
$this->app->singleton(EntityManager::class, function () {
$config = ORMSetup::createAttributeMetadataConfig(paths: [__DIR__ . '/src'], isDevMode: true);
$config->setProxyDir('/tmp');
$config->setProxyNamespace('App\\Doctrine');
$connection = DriverManager::getConnection([ 'driver' => 'pdo_sqlite', 'path' => __DIR__ . '/db.sqlite'], $config);
return new EntityManager($connection, $config);
});
}
public function provides(): array
{
return [ EntityManager::class ];
}
}
EOF-
Run the meta command:
php artisan ide-helper:meta -
This will trigger the error:
Symfony\Component\ErrorHandler\Error\FatalError
During class fetch: Uncaught ReflectionException: Class 'Doctrine\Persistence\Mapping\StaticReflectionService' not found. in /opt/app/vendor/barryvdh/laravel-ide-helper/src/Console/MetaCommand.php:203
Stack trace:
#0 [internal function]: Barryvdh\LaravelIdeHelper\Console\MetaCommand->{closure:Barryvdh\LaravelIdeHelper\Console\MetaCommand::registerClassAutoloadExceptions():197}('Doctrine\\Persis...')
#1 /opt/app/vendor/doctrine/orm/src/Mapping/GetReflectionClassImplementation.php(12): class_exists('Doctrine\\Persis...')
#2 /opt/app/vendor/composer/ClassLoader.php(576): include('/opt/app/vendor...')
#3 /opt/app/vendor/composer/ClassLoader.php(427): {closure:Composer\Autoload\ClassLoader::initializeIncludeClosure():575}('/opt/app/vendor...')
#4 /opt/app/vendor/doctrine/orm/src/Mapping/ClassMetadata.php(81): Composer\Autoload\ClassLoader->loadClass('Doctrine\\ORM\\Ma...')
#5 /opt/app/vendor/composer/ClassLoader.php(576): include('/opt/app/vendor...')
#6 /opt/app/vendor/composer/ClassLoader.php(427): {closure:Composer\Autoload\ClassLoader::initializeIncludeClosure():575}('/opt/app/vendor...')
#7 /opt/app/vendor/doctrine/orm/src/EntityManagerInterface.php(20): Composer\Autoload\ClassLoader->loadClass('Doctrine\\ORM\\Ma...')
#8 /opt/app/vendor/composer/ClassLoader.php(576): include('/opt/app/vendor...')
#9 /opt/app/vendor/composer/ClassLoader.php(427): {closure:Composer\Autoload\ClassLoader::initializeIncludeClosure():575}('/opt/app/vendor...')
#10 /opt/app/vendor/doctrine/orm/src/EntityManager.php(60): Composer\Autoload\ClassLoader->loadClass('Doctrine\\ORM\\En...')
#11 /opt/app/vendor/composer/ClassLoader.php(576): include('/opt/app/vendor...')
#12 /opt/app/vendor/composer/ClassLoader.php(427): {closure:Composer\Autoload\ClassLoader::initializeIncludeClosure():575}('/opt/app/vendor...')
#13 /opt/app/app/Providers/DoctrineServiceProvider.php(20): Composer\Autoload\ClassLoader->loadClass('Doctrine\\ORM\\En...')
#14 /opt/app/vendor/laravel/framework/src/Illuminate/Container/Container.php(1115): App\Providers\DoctrineServiceProvider->{closure:App\Providers\DoctrineServiceProvider::register():15}(Object(Illuminate\Foundation\Application), Array)
#15 /opt/app/vendor/laravel/framework/src/Illuminate/Container/Container.php(933): Illuminate\Container\Container->build(Object(Closure))
#16 /opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1078): Illuminate\Container\Container->resolve('Doctrine\\ORM\\En...', Array, true)
#17 /opt/app/vendor/laravel/framework/src/Illuminate/Container/Container.php(864): Illuminate\Foundation\Application->resolve('Doctrine\\ORM\\En...', Array)
#18 /opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1058): Illuminate\Container\Container->make('Doctrine\\ORM\\En...', Array)
#19 /opt/app/vendor/barryvdh/laravel-ide-helper/src/Console/MetaCommand.php(124): Illuminate\Foundation\Application->make('Doctrine\\ORM\\En...')
#20 /opt/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Barryvdh\LaravelIdeHelper\Console\MetaCommand->handle()
#21 /opt/app/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\Container\BoundMethod::{closure:Illuminate\Container\BoundMethod::call():35}()
#22 /opt/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\Container\Util::unwrapIfClosure(Object(Closure))
#23 /opt/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
#24 /opt/app/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
#25 /opt/app/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\Container\Container->call(Array)
#26 /opt/app/vendor/symfony/console/Command/Command.php(341): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#27 /opt/app/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#28 /opt/app/vendor/symfony/console/Application.php(1102): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#29 /opt/app/vendor/symfony/console/Application.php(356): Symfony\Component\Console\Application->doRunCommand(Object(Barryvdh\LaravelIdeHelper\Console\MetaCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#30 /opt/app/vendor/symfony/console/Application.php(195): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#31 /opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#32 /opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#33 /opt/app/artisan(16): Illuminate\Foundation\Application->handleCommand(Object(Symfony\Component\Console\Input\ArgvInput))
#34 {main}
at vendor/doctrine/orm/src/Mapping/ClassMetadata.php:81
77▕ * @phpstan-type ConcreteAssociationMapping = OneToOneOwningSideMapping|OneToOneInverseSideMapping|ManyToOneAssociationMapping|OneToManyAssociationMapping|ManyToManyOwningSideMapping|ManyToManyInverseSideMapping
78▕ * @template-covariant T of object
79▕ * @template-implements PersistenceClassMetadata<T>
80▕ */
➜ 81▕ class ClassMetadata implements PersistenceClassMetadata, Stringable
82▕ {
83▕ use GetReflectionClassImplementation;
84▕
85▕ /* The inheritance mapping types */
Whoops\Exception\ErrorException
During class fetch: Uncaught ReflectionException: Class 'Doctrine\Persistence\Mapping\StaticReflectionService' not found. in /opt/app/vendor/barryvdh/laravel-ide-helper/src/Console/MetaCommand.php:203
Stack trace:
#0 [internal function]: Barryvdh\LaravelIdeHelper\Console\MetaCommand->{closure:Barryvdh\LaravelIdeHelper\Console\MetaCommand::registerClassAutoloadExceptions():197}('Doctrine\\Persis...')
#1 /opt/app/vendor/doctrine/orm/src/Mapping/GetReflectionClassImplementation.php(12): class_exists('Doctrine\\Persis...')
#2 /opt/app/vendor/composer/ClassLoader.php(576): include('/opt/app/vendor...')
#3 /opt/app/vendor/composer/ClassLoader.php(427): {closure:Composer\Autoload\ClassLoader::initializeIncludeClosure():575}('/opt/app/vendor...')
#4 /opt/app/vendor/doctrine/orm/src/Mapping/ClassMetadata.php(81): Composer\Autoload\ClassLoader->loadClass('Doctrine\\ORM\\Ma...')
#5 /opt/app/vendor/composer/ClassLoader.php(576): include('/opt/app/vendor...')
#6 /opt/app/vendor/composer/ClassLoader.php(427): {closure:Composer\Autoload\ClassLoader::initializeIncludeClosure():575}('/opt/app/vendor...')
#7 /opt/app/vendor/doctrine/orm/src/EntityManagerInterface.php(20): Composer\Autoload\ClassLoader->loadClass('Doctrine\\ORM\\Ma...')
#8 /opt/app/vendor/composer/ClassLoader.php(576): include('/opt/app/vendor...')
#9 /opt/app/vendor/composer/ClassLoader.php(427): {closure:Composer\Autoload\ClassLoader::initializeIncludeClosure():575}('/opt/app/vendor...')
#10 /opt/app/vendor/doctrine/orm/src/EntityManager.php(60): Composer\Autoload\ClassLoader->loadClass('Doctrine\\ORM\\En...')
#11 /opt/app/vendor/composer/ClassLoader.php(576): include('/opt/app/vendor...')
#12 /opt/app/vendor/composer/ClassLoader.php(427): {closure:Composer\Autoload\ClassLoader::initializeIncludeClosure():575}('/opt/app/vendor...')
#13 /opt/app/app/Providers/DoctrineServiceProvider.php(20): Composer\Autoload\ClassLoader->loadClass('Doctrine\\ORM\\En...')
#14 /opt/app/vendor/laravel/framework/src/Illuminate/Container/Container.php(1115): App\Providers\DoctrineServiceProvider->{closure:App\Providers\DoctrineServiceProvider::register():15}(Object(Illuminate\Foundation\Application), Array)
#15 /opt/app/vendor/laravel/framework/src/Illuminate/Container/Container.php(933): Illuminate\Container\Container->build(Object(Closure))
#16 /opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1078): Illuminate\Container\Container->resolve('Doctrine\\ORM\\En...', Array, true)
#17 /opt/app/vendor/laravel/framework/src/Illuminate/Container/Container.php(864): Illuminate\Foundation\Application->resolve('Doctrine\\ORM\\En...', Array)
#18 /opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1058): Illuminate\Container\Container->make('Doctrine\\ORM\\En...', Array)
#19 /opt/app/vendor/barryvdh/laravel-ide-helper/src/Console/MetaCommand.php(124): Illuminate\Foundation\Application->make('Doctrine\\ORM\\En...')
#20 /opt/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(36): Barryvdh\LaravelIdeHelper\Console\MetaCommand->handle()
#21 /opt/app/vendor/laravel/framework/src/Illuminate/Container/Util.php(43): Illuminate\Container\BoundMethod::{closure:Illuminate\Container\BoundMethod::call():35}()
#22 /opt/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(96): Illuminate\Container\Util::unwrapIfClosure(Object(Closure))
#23 /opt/app/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(35): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
#24 /opt/app/vendor/laravel/framework/src/Illuminate/Container/Container.php(799): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
#25 /opt/app/vendor/laravel/framework/src/Illuminate/Console/Command.php(211): Illuminate\Container\Container->call(Array)
#26 /opt/app/vendor/symfony/console/Command/Command.php(341): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#27 /opt/app/vendor/laravel/framework/src/Illuminate/Console/Command.php(180): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
#28 /opt/app/vendor/symfony/console/Application.php(1102): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#29 /opt/app/vendor/symfony/console/Application.php(356): Symfony\Component\Console\Application->doRunCommand(Object(Barryvdh\LaravelIdeHelper\Console\MetaCommand), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#30 /opt/app/vendor/symfony/console/Application.php(195): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#31 /opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(198): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#32 /opt/app/vendor/laravel/framework/src/Illuminate/Foundation/Application.php(1235): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
#33 /opt/app/artisan(16): Illuminate\Foundation\Application->handleCommand(Object(Symfony\Component\Console\Input\ArgvInput))
#34 {main}
at vendor/doctrine/orm/src/Mapping/ClassMetadata.php:81
77▕ * @phpstan-type ConcreteAssociationMapping = OneToOneOwningSideMapping|OneToOneInverseSideMapping|ManyToOneAssociationMapping|OneToManyAssociationMapping|ManyToManyOwningSideMapping|ManyToManyInverseSideMapping
78▕ * @template-covariant T of object
79▕ * @template-implements PersistenceClassMetadata<T>
80▕ */
➜ 81▕ class ClassMetadata implements PersistenceClassMetadata, Stringable
82▕ {
83▕ use GetReflectionClassImplementation;
84▕
85▕ /* The inheritance mapping types */
+1 vendor frames
2 [internal]:0
Whoops\Run::handleShutdown()