8000 [4.1] The "parameter_bag" service is not available. · Issue #27436 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[4.1] The "parameter_bag" service is not available. #27436

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
emulienfou opened this issue May 30, 2018 · 20 comments
Closed

[4.1] The "parameter_bag" service is not available. #27436

emulienfou opened this issue May 30, 2018 · 20 comments

Comments

@emulienfou
Copy link

Symfony version(s) affected: 4.1.0

Description
Since updated to Symfony 4.1, I switch to use AbstractController instead of Controller class, as suggested!

However, I receive now the LogicExtension: The "parameter_bag" service is not available. Try running "composer require dependency-injection:^4.1".

It seems the the service parameter_bag is not public and cannot be acceded!

Using the debug command: php bin/console debug:container parameter_bag

Information for Service "parameter_bag"
=======================================

 ---------------- ----------------------------------------------------------------- 
  Option           Value                                                            
 ---------------- ----------------------------------------------------------------- 
  Service ID       parameter_bag                                                    
  Class            Symfony\Component\DependencyInjection\ParameterBag\ContainerBag  
  Tags             -                                                                
  Public           no                                                               
  Synthetic        no                                                               
  Lazy             no                                                               
  Shared           yes                                                              
  Abstract         no                                                               
  Autowired        no                                                               
  Autoconfigured   no                                                               
 ---------------- ----------------------------------------------------------------- 

How to reproduce

class TestController extends AbstractController
{
    public function index()
    {
       // ...
       $variable = $this->getParameter('service_name');
       // ...
    }
}

Possible Solution
In the file: framework-bundle/Resources/config/services.xml

Change:

<service id="parameter_bag" class="Symfony\Component\DependencyInjection\ParameterBag\ContainerBag">
        <argument type="service" id="service_container" />
</service>

By:

<service id="parameter_bag" class="Symfony\Component\DependencyInjection\ParameterBag\ContainerBag" public="true">
        <argument type="service" id="service_container" />
 </service>

To make the service has public seems to resolve the issue!

@curry684
Copy link
Contributor

The service doesn't have to be public as the AbstractController injects it in a private service locator. Does the problem occur again if you change it back to private now? You may have just into a caching issue.

@emulienfou
Copy link
Author

I already try that, if I put the service back to private the problem is not occurring.
However when I clear my cache the problem occur again! So there is an issue for me

@curry684
Copy link
Contributor

Can you share the output of composer show | grep symfony?

If on a Windows system just run composer show and copy/paste all lines beginning with symfony.

@emulienfou
Copy link
Author
symfony/asset                       v4.1.0               Symfony Asset Component
symfony/cache                       v4.1.0               Symfony Cache component with PSR-6, PSR-16, and tags
symfony/config                      v4.1.0               Symfony Config Component
symfony/console                     v4.1.0               Symfony Console Component
symfony/debug                       v4.1.0               Symfony Debug Component
symfony/dependency-injection        v4.1.0               Symfony DependencyInjection Component
symfony/doctrine-bridge             v4.1.0               Symfony Doctrine Bridge
symfony/dotenv                      v4.1.0               Registers environment variables from a .env file
symfony/event-dispatcher            v4.1.0               Symfony EventDispatcher Component
symfony/filesystem                  v4.1.0               Symfony Filesystem Component
symfony/finder                      v4.1.0               Symfony Finder Component
symfony/flex                        v1.0.80             
symfony/form                        v4.1.0               Symfony Form Component
symfony/framework-bundle            v4.1.0               Symfony FrameworkBundle
symfony/http-foundation             v4.1.0               Symfony HttpFoundation Component
symfony/http-kernel                 v4.1.0               Symfony HttpKernel Component
symfony/inflector                   v4.1.0               Symfony Inflector Component
symfony/intl                        v4.1.0               A PHP replacement layer for the C intl extension that includes additional data from the ICU library.
symfony/lts                         dev-master 6de50b2   Enforces Long Term Supported versions of Symfony components
symfony/maker-bundle                v1.5.0               Symfony Maker helps you create empty commands, controllers, form classes, tests and more so you can forget about writing boilerplate code.
symfony/monolog-bridge              v4.1.0               Symfony Monolog Bridge
symfony/monolog-bundle              v3.2.0               Symfony MonologBundle
symfony/options-resolver            v4.1.0               Symfony OptionsResolver Component
symfony/polyfill-ctype              v1.8.0               Symfony polyfill for ctype functions
symfony/polyfill-intl-icu           v1.8.0               Symfony polyfill for intl's ICU-related data and classes
symfony/polyfill-mbstring           v1.8.0               Symfony polyfill for the Mbstring extension
symfony/polyfill-php72              v1.8.0               Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions
symfony/profiler-pack               v1.0.3               A pack for the Symfony web profiler
symfony/property-access             v4.1.0               Symfony PropertyAccess Component
symfony/routing                     v4.1.0               Symfony Routing Component
symfony/security                    v4.1.0               Symfony Security Component
symfony/security-bundle             v4.1.0               Symfony SecurityBundle
symfony/serializer                  v4.1.0               Symfony Serializer Component
symfony/stopwatch                   v4.1.0               Symfony Stopwatch Component
symfony/swiftmailer-bundle          v3.2.2               Symfony SwiftmailerBundle
symfony/templating                  v4.1.0               Symfony Templating Component
symfony/translation                 v4.1.0               Symfony Translation Component
symfony/twig-bridge                 v4.1.0               Symfony Twig Bridge
symfony/twig-bundle                 v4.1.0               Symfony TwigBundle
symfony/validator                   v4.1.0               Symfony Validator Component
symfony/var-dumper                  v4.1.0               Symfony mechanism for exploring and dumping PHP variables
symfony/web-profiler-bundle         v4.1.0               Symfony WebProfilerBundle
symfony/webpack-encore-pack         v1.0.2               A pack for Symfony Encore
symfony/yaml                        v4.1.0               Symfony Yaml Component

@curry684
Copy link
Contributor

Ok that should all be fine. I cannot reproduce your issue however. I suspect in migrating from Controller to AbstractController you didn't clean up the config correctly. The issue you describe would occur if you are manually injecting @service_container in your controller and storing it in $this->container, thereby hiding the locator. This would show if dump(get_class($this->container)); in the controller would show anything other than ServiceLocator.

Would it be possible for you to create a reproducer?

@emulienfou
Copy link
Author

Trying to reproduce the issue, but not so simple.
However when I do var_dump(get_class($this->container));

  • I got: Symfony\Component\DependencyInjection\ServiceLocator from the skeleton,
  • However, I got Container9Izl7V4\srcDevDebugProjectContainer in my project.

@emulienfou
Copy link
Author

Hi there, I create a reproducer here: https://github.com/emulienfou/symfony_issue_27436
I successfully reproduce the bug.

The issue is when trying to access to the ParameterBag service, using $this->container->has('parameter_bag') directly from a controller in a Symfony project, it's working perfectly.

However, if you are trying to do the same in a bundle, the ParameterBag service seems to be not available.

You can try my reproducer by accessing directly to: http://issue_27436.symfony:9999 using my docker configuration to the App controller. It will display true.
You can also access to: http://issue_27436.symfony:9999/issue to display the response of the same code: false

@ogizanagi
Copy link
Contributor

@emulienfou : The issue is that your bundle controller is not manually wired, nor autowired nor autoconfigured, so ServiceSubscriberInterface is not detected and corresponding tag not added. Hence service locator is not injected. Your bundle misses wiring the controller properly.

@curry684
Copy link
Contributor
curry684 commented May 31, 2018

Although this indeed makes it not a bug I'm surprised AbstractController then gets the full container indeed by default instead of erroring out verbosely, there is definitely a DX issue there methinks.

@ogizanagi
Copy link
Contributor

That's because of

if ($controller instanceof AbstractController && null !== $previousContainer = $controller->setContainer($this->container)) {
$controller->setContainer($previousContainer);
}

I don't remember what motivated this.

@ogizanagi
Copy link
Contributor

@javiereguiluz javiereguiluz changed the title [Bug][4.1] The "parameter_bag" service is not available. [4.1] The "parameter_bag" service is not available. May 31, 2018
@curry684
Copy link
Contributor

Hmm ok the reasoning there is not unfair, but the result seen in this issue is most unfortunate and I understand the confusion.

@weaverryan @nicolas-grekas what's your opinion on this?

@nicolas-grekas
Copy link
Member
nicolas-grekas commented May 31, 2018

My opinion is that the core issue is a bad configuration, it needs to be fixed there :)
And the exception message also should be changed, "Try running "composer require dependency-injection:^4.1"" is odd.

@curry684
Copy link
Contributor
curry684 commented May 31, 2018

Yeah no contest that it's a configuration issue, just pointing 8000 out the DX sucks if you run into this situation. First of all we could actually detect DI being installed at runtime before throwing the current exception, and then fix both by changing the alternative exception to something like "The parameter_bag service could not be located. Ensure that the controller is either set to be autoconfigured or wired manually to inject it".

@nicolas-grekas
Copy link
Member

Yep. PR welcome :)
About DI, it is always installed, but not necessarily at v4.1, that's what the current message is about (but is wrong in this case, so yes, more logic is needed here to provide an accurate message)

@emulienfou
Copy link
Author
emulienfou commented May 31, 2018

Thanks for that!
However @ogizanagi , how can I wire/autowire my controller?

Tried something like:

services:
  App\Issue27436Bundle\Controller\:
    resource: ../../Controller
    autowire: true

But is not working ;(

@nicolas-grekas
Copy link
Member

PR to improve the message is #27443, more reviews welcome.

@curry684
Copy link
Contributor

@emulienfou you should also add autoconfigure: true

Autowire = try to automatically inject right services based on typehints
Autoconfigure = try to automatically add behaviors to service based on common interfaces or base classes

In this case the autoconfigure is required to pick up the ServiceSubscriberInterface which injects a bunch of services (like parameter_bag via a much smaller and more performant ServiceLocator rather than the entire container as it was before.

Also see https://symfony.com/blog/new-in-symfony-3-3-service-autoconfiguration

@emulienfou
Copy link
Author
emulienfou commented Jun 1, 2018

After adding the autoconfigure: true, I've got an other exception who may be related:
Service "dcs_rating.manager.rating" not found: even though it exists in the app's container, the container inside "App\Issue27436Bundle\Controller\Issue27436Controller" is a smaller service locator that only knows about the "doctrine", "http_kernel", "parameter_bag", "request_stack", "router", "security.authorization_checker", "security.csrf.token_manager", "security.token_storage", "session" and "twig" services. Unless you need extra laziness, try using dependency injection instead. Otherwise, you need to declare it using "Issue27436Controller::getSubscribedServices()".

I just update my reproducer code: https://github.com/emulienfou/symfony_issue_27436

@curry684
Copy link
Contributor
curry684 commented Jun 1, 2018

That error has no lack of DX at all and explicitly tells you how to fix it.

chalasr pushed a commit that referenced this issue Jun 4, 2018
…getParameter fails (curry684)

This PR was squashed before being merged into the 4.1 branch (closes #27443).

Discussion
----------

[DX] Improve exception message when AbstractController::getParameter fails

| Q             | A
| ------------- | ---
| Branch?       | 4.1
| Bug fix?      | no (DX)
| New feature?  | no
| BC breaks?    | no     <!-- see https://symfony.com/bc -->
| Deprecations? | no
| Tests pass?   | yes    <!-- please add some, will be required by reviewers -->
| Fixed tickets | #27436
| License       | MIT
| Doc PR        | symfony/symfony-docs#... <!-- required for new features -->

Improve exception message for situations where the `parameter_bag` is not present in `AbstractController`. Also fixed the exception to the correct type.

Commits
-------

a8f4128 [DX] Improve exception message when AbstractController::getParameter fails
@chalasr chalasr closed this as completed Jun 4, 2018
nicolas-grekas added a commit that referenced this issue Jun 4, 2018
…ainer in AbstractController instances (nicolas-grekas)

This PR was merged into the 4.2-dev branch.

Discussion
----------

[FrameworkBundle] Deprecate auto-injection of the container in AbstractController instances

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | no
| BC breaks?    | no
| Deprecations? | yes
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

Should enhance DX by preventing situations like #27436.

Commits
-------

e2f344f [FrameworkBundle] Deprecate auto-injection of the container in AbstractController instances
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants
0