magento / magento2

Prior to making any Submission(s), you must sign an Adobe Contributor License Agreement, available here at: https://opensource.adobe.com/cla.html. All Submissions you make to Adobe Inc. and its affiliates, assigns and subsidiaries (collectively “Adobe”) are subject to the terms of the Adobe Contributor License Agreement.
http://www.magento.com
Open Software License 3.0
11.48k stars 9.29k forks source link

I got this after bin/magento setup:di:compile #4896

Closed webkulabhi closed 6 years ago

webkulabhi commented 8 years ago
<b>Fatal error</b>:  Uncaught TypeError: Argument 1 passed to Magento\Setup\Module\DataSetup::__construct
() must be an instance of Magento\Framework\Module\Setup\Context, instance of Magento\Framework\ObjectManager
\ObjectManager given, called in /var/www/html/pro2/lib/internal/Magento/Framework/ObjectManager/Factory
/AbstractFactory.php on line 97 and defined in /var/www/html/pro2/setup/src/Magento/Setup/Module/DataSetup
.php:57
Stack trace:
#0 /var/www/html/pro2/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php(97): Magento
\Setup\Module\DataSetup-&gt;__construct(Object(Magento\Framework\ObjectManager\ObjectManager))
#1 /var/www/html/pro2/lib/internal/Magento/Framework/ObjectManager/Factory/Compiled.php(88): Magento
\Framework\ObjectManager\Factory\AbstractFactory-&gt;createObject('Magento\\Setup\\M...', Array)
#2 /var/www/html/pro2/lib/internal/Magento/Framework/ObjectManager/Factory/Compiled.php(130): Magento
\Framework\ObjectManager\Factory\Compiled-&gt;create('Magento\\Setup\\M...')
#3 /var/www/html/pro2/lib/interna in <b>/var/www/html/pro2/setup/src/Magento/Setup/Module/DataSetup.php
</b> on line <b>57</b><br />

magento is in Default mode... When i removed var/di error removed. But when i again run bin/magento setup:di:compile i got same error . magento version 2.0.7

davidalger commented 8 years ago

@webkulabhi What version of PHP are you running?

webkulabhi commented 8 years ago

@davidalger running on php 7.0.6

webkulabhi commented 8 years ago

PHP 5.6.22 After delete var/di... its worked properly

[2016-06-17 11:37:24] main.CRITICAL: exception 'Exception' with message 'Recoverable Error: Argument 1 passed to Magento\Framework\Model\AbstractModel::__construct() must be an instance of Magento\Framework\Model\Context, instance of Magento\Framework\ObjectManager\ObjectManager given, called in /home/abhishek/www/html/mage1/lib/internal/Magento/Framework/ObjectManager/Factory/AbstractFactory.php on line 97 and defined in /home/abhishek/www/html/mage1/lib/internal/Magento/Framework/Model/AbstractModel.php on line 171' in /home/abhishek/www/html/mage1/lib/internal/Magento/Framework/App/ErrorHandler.php:61

oserediuk commented 8 years ago

Hello! Please, provide the used version. If the problem is actual for a specific branch, please, specify it and be sure that the latest update was used.

webkulabhi commented 8 years ago

i used magento version 2.0.7 i did not find this issues in magento2.1.0

bartoszkubicki commented 8 years ago

same here on 2.1, disapperas when var/di is deleted manually.

ruudniew commented 8 years ago

Same here. When recompiling the error appears again. Will update when I find the solution to this.

ruudniew commented 8 years ago

The solution for me was not using Setup classes outside of the setup. I tried to implement the code given in the following articles / questions: http://magento.stackexchange.com/questions/103934/magento2-programmatically-add-product-attribute-options https://webkul.com/blog/programmatically-add-options-attribute-magento2/ https://www.atwix.com/magento/adding-attribute-programatically-magento2/

They all want to use the Magento\Eav\Setup\EavSetupFactory or even the \Magento\Catalog\Setup\CategorySetupFactory class, which you shouldn't use outside the setup. The code I used now:

  protected $_logger;

  protected $_attributeRepository;

  protected $_attributeOptionManagement;

  protected $_option;

  protected $_attributeOptionLabel;

   public function __construct(
      \Psr\Log\LoggerInterface $logger,
      \Magento\Eav\Model\AttributeRepository $attributeRepository,
      \Magento\Eav\Api\AttributeOptionManagementInterface $attributeOptionManagement,
      \Magento\Eav\Api\Data\AttributeOptionLabelInterface $attributeOptionLabel,
      \Magento\Eav\Model\Entity\Attribute\Option $option
    ){
      $this->_logger = $logger;
      $this->_attributeRepository = $attributeRepository;
      $this->_attributeOptionManagement = $attributeOptionManagement;
      $this->_option = $option;
      $this->_attributeOptionLabel = $attributeOptionLabel;
   }

Then in the function:

 $attribute_id = $this->_attributeRepository->get('catalog_product', 'your_attribute')->getAttributeId();
  $options = $this->_attributeOptionManagement->getItems('catalog_product', $attribute_id);
  /* if attribute option already exists, remove it */
  foreach($options as $option) {
    if ($option->getLabel() == $oldname) {
      $this->_attributeOptionManagement->delete('catalog_product', $attribute_id, $option->getValue());
    }
  }

  /* new attribute option */
    $this->_option->setValue($name);
    $this->_attributeOptionLabel->setStoreId(0);
    $this->_attributeOptionLabel->setLabel($name);
    $this->_option->setLabel($this->_attributeOptionLabel);
    $this->_option->setStoreLabels([$this->_attributeOptionLabel]);
    $this->_option->setSortOrder(0);
    $this->_option->setIsDefault(false);
    $this->_attributeOptionManagement->add('catalog_product', $attribute_id, $this->_option);
quickshiftin commented 8 years ago

I had this same issue, @ruudniew nailed it. In a Console Command of mine, I had to change Magento\Catalog\Setup\CategorySetup to Magento\Catalog\Model\Config in the __construct arguments for a call to getAttributeSetId(). Works like a charm now.

jignesh26 commented 8 years ago

I had same issue in magento 2.1.

I am calling Image render from the grid block. $this->addColumn( 'image', [ 'header' => __('image'), 'index' => 'image', 'class' => 'image', 'renderer'=> 'Main\Module\Block\Adminhtml\Grid\Renderer\Image', ] and here is my Image render class `namespace Main\Module\Block\Adminhtml\Grid\Renderer;

use Magento\Backend\Block\Widget\Grid\Column\Renderer\AbstractRenderer; use Magento\Framework\DataObject; use Magento\Store\Model\StoreManagerInterface; use Magento\Backend\Block\Context; use Magento\Catalog\Model\ResourceModel\Eav\AttributeFactory; use Magento\Framework\Registry;

class Image extends AbstractRenderer{

private $_storeManager;
protected $registry;
protected $attributeFactory;

public function __construct(\Magento\Backend\Block\Context $context, StoreManagerInterface $storemanager, array $data = []) { $this->_storeManager = $storemanager; parent::__construct($context, $data); $this->_authorization = $context->getAuthorization(); }

public function render(\Magento\Framework\DataObject $row)    {        
return '<img src="" >is wokring';
}   

} `

But without di compile works very well but after the Di compile shows the error _must be an instance of Magento\Backend\Block\Context, instance of Magento\Framework\ObjectManager\ObjectManager given, called in /var/www/html/projects/mag3/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php on line 93 in _

duongdiep212 commented 8 years ago

Hi there, I've get the same issue after run the php bin/magento setup:di:compile Really, I don't know how I can fix the issue without delete var/di ?

Recoverable Error: Argument 1 passed to Magento\Setup\Module\DataSetup::__construct() must be an instance of Magento\Framework\Module\Setup\Context, instance of Magento\Framework\ObjectManager\ObjectManager given, called in /home/opumo/subdomains/devm2/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php on line 93 and defined in /home/opumo/subdomains/devm2/setup/src/Magento/Setup/Module/DataSetup.php on line 58

jignesh26 commented 8 years ago

@duongdiep212 If the issue is related to Bug than you can skip this issue by doing this steps.

php bin/magento setup:di:compile -vv php bin/magento setup:upgrade php bin/magento setup:static-content:deploy

Run above command in same sequence and than do only cache clean whenever required .

this works for me until magento investigate this issue.

duongdiep212 commented 8 years ago

Hi @jignesh26 many thanks for help, but still get the error after run the command : php bin/magento setup:upgrade

Warning: file_get_contents(/home/opumo/subdomains/devm2/var/di/setup.ser):
failed to open stream: No such file or directory in /home/opumo/subdomains/
devm2/vendor/magento/framework/App/ObjectManager/ConfigLoader/Compiled.php
on line 28

regarding the issue : Recoverable Error: Argument 1 passed to Magento\Setup\Module\DataSetup::__construct() must be an instance of Magento\Framework\Module\Setup\Context the issue is appear if I enable my module in app/etc/config.php , my module is working normal until run the command php bin/magento setup:di:compile

looking forward to hearing from you.

jignesh26 commented 8 years ago

@duongdiep212 So sad to hear that , when you gets the Setup.ser error. Just Remove whole generation Folder and DI folder. and try my given steps. otherwise let me know we will solve it together.

Try this one also bit of hack. just delete the var directory and Deploy the content and try to access your site admin and frontend.

Thank you , looking forward to hearing from you..

davidwatson1090 commented 8 years ago

@quickshiftin Can You please explain the procedure how you resolved this??

marcatos commented 8 years ago

@chriss-jordan I solved this issue refactoring my module as described here http://magento.stackexchange.com/a/128438/44884

I hope this would help you

quickshiftin commented 8 years ago

Hi @chriss-jordan, like @ruudniew I was using a Setup class outside of the setup. So I had this

use Symfony\Component\Console\Command\Command;
use Magento\Catalog\Setup\CategorySetup;

class SyncProducts extends Command
{
    private $_iGroceryAttrSetId;

    public function __construct(CategorySetup $oInstaller)
    {
        $this->_iGroceryAttrSetId = $oInstaller->getAttributeSetId('catalog_product', 'grocery');
    }
}

I took @ruudniew's advice and changed it to

use Symfony\Component\Console\Command\Command;
use Magento\Catalog\Model\Config as ModelConfig;

class SyncProducts extends Command
{
    private $_iGroceryAttrSetId;

    public function __construct(ModelConfig $oModelConfig)
    {
        $this->_iGroceryAttrSetId = $oModelConfig->getAttributeSetId('catalog_product', 'grocery');
    }
}
davidwatson1090 commented 8 years ago

Hi @quickshiftin, thnx for sharing this....actually i had a problem in assiging attributes to attribute set and i was using this this->_objectManager->create('Magento\Eav\Setup\EavSetup')->addAttributeToSet() and it was throwing the error...so i got the the other solution now i ued this $this->_objectManager->get('Magento\Eav\Model\AttributeManagement')->assign() and it worked for me;

oshmyheliuk commented 7 years ago

Hi @webkulabhi , Unfortunately, I could not reproduce the issue as you described it. Is this issue still actual?

djfordz commented 7 years ago

Hello,

I just ran into same issue.

[29-Nov-2016 16:10:15 UTC] PHP Fatal error:  Uncaught TypeError: Argument 1 passed to Magento\Setup\Module\DataSetup::__construct() must be an instance of Magento\Framework\Module\Setup\Context, instance of Magento\Framework\ObjectManager\ObjectManager given, called in /home/sound/m2/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php on line 93 and defined in /home/sound/m2/setup/src/Magento/Setup/Module/DataSetup.php:57
Stack trace:
#0 /home/sound/m2/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php(93): Magento\Setup\Module\DataSetup->__construct(Object(Magento\Framework\ObjectManager\ObjectManager))
#1 /home/sound/m2/vendor/magento/framework/ObjectManager/Factory/Compiled.php(88): Magento\Framework\ObjectManager\Factory\AbstractFactory->createObject('Magento\\Setup\\M...', Array)
#2 /home/sound/m2/vendor/magento/framework/ObjectManager/Factory/Compiled.php(130): Magento\Framework\ObjectManager\Factory\Compiled->create('Magento\\Setup\\M...')
#3 /home/sound/m2/vendor/magento/framework/ObjectManager/Factory/Compiled.php in /home/sound/m2/setup/src/Magento/Setup/Module/DataSetup.php on line 57

Here is the app/code folder: Amasty CommerceExtensions Emizentech Ibnab Mageplaza Magestore MagicToolbox Plumrocket Smartwave WeProvide

Probably an issue with one of these modules and not Magento itself.

djfordz commented 7 years ago

Also get this when I initially run the command

The directory "/home/sound/m2/var/generation/Magento/Framework" cannot be deleted Warning!rmdir(/home/sound/m2/var/generation/Magento/Framework): Directory not empty#0 /home/sound/m2/vendor/magento/framework/Filesystem/Driver/File.php(403): Magento\Framework\Filesystem\Driver\File->deleteDirectory('/home/sound/m2/...')
#1 /home/sound/m2/vendor/magento/framework/Filesystem/Driver/File.php(403): Magento\Framework\Filesystem\Driver\File->deleteDirectory('/home/sound/m2/...')
#2 /home/sound/m2/setup/src/Magento/Setup/Console/CompilerPreparation.php(68): Magento\Framework\Filesystem\Driver\File->deleteDirectory('/home/sound/m2/...')
#3 /home/sound/m2/vendor/magento/framework/Console/Cli.php(74): Magento\Setup\Console\CompilerPreparation->handleCompilerEnvironment()
#4 /home/sound/m2/bin/magento(22): Magento\Framework\Console\Cli->__construct('Magento CLI')
#5 {main}

PHP Fatal error:  Uncaught Error: Class 'Cli' not found in /home/sound/m2/bin/magento:31
Stack trace:
#0 {main}
  thrown in /home/sound/m2/bin/magento on line 31

but when I run it again it processes normally.

rzinnatullin commented 7 years ago

Same issue here:

[2016-12-23 05:48:45] main.CRITICAL: exception 'Exception' with message 'Recoverable Error: Argument 1 passed to Magento\Setup\Module\DataSetup::__construct() must be an instance of Magento\Framework\Module\Setup\Context, instance of Magento\Framework\ObjectManager\ObjectManager given, called in C:\xampp2\apps\magento\htdocs\vendor\magento\framework\ObjectManager\Factory\AbstractFactory.php on line 93 and defined in C:\xampp2\apps\magento\htdocs\setup\src\Magento\Setup\Module\DataSetup.php on line 58' in C:\xampp2\apps\magento\htdocs\vendor\magento\framework\App\ErrorHandler.php:61

I'm using \Magento\Framework\Setup\ModuleDataSetupInterface in one of my classes I use in REST API.

    public function __construct(
            \Magento\Customer\Setup\CustomerSetupFactory $factory,
            \Magento\Framework\Setup\ModuleDataSetupInterface $setup,   <=============
            ...

Then in code I am adding an attribute like this:

        $customerSetup = $this->customerSetupFactory->create(['setup' => $this->setup]);
        $this->setup->startSetup();
        ...
        $customerSetup->addAttribute($entityTypeId, $attrId, $attrData);
        $customerSetup->getEavConfig()->clear(); // Need to clear cache because $customerSetup->addAttribute doesn't update the cache
        $attr = $customerSetup->getEavConfig()->getAttribute($entityType, $attrId);
        $attr->addData($attrData);
        $attr->save();
        $this->setup->endSetup();

Any suggestions how to rewrite my code in order not to use Setup outside of the setup? Magento 2.1.2 PHP 5.6

djfordz commented 7 years ago

I'm getting this specifically with certain modules so, I am sure it is not a Magento issue, but an issue regarding Module developers, the only problem is, how to fix the module developers to write correct code. Manadev seems to be the culprit in my case.

ekuusela commented 7 years ago

I didn't see an official response or a piece of documentation about using setup classes outside of setup, so I asked Magento enterprice support and they confirmed that currently setup classes are indeed not meant to be used outside of setup.

Pigau commented 7 years ago

We had this problem too and we found that the Setup Context seem to not be injectable. But we didn't find a good solution to this problem.

guvra commented 7 years ago

The setup class is indeed not injectable. In production mode, the object manager fails to create the object.

I used the following workaround:

// DataSetup is not injectable
$context = $this->objectManager->get('Magento\Framework\Module\Setup\Context');
$dataSetup = new DataSetup($context);
jalogut commented 7 years ago

Hi @Pigau , the Setup Context is indeed not injectable because the whole Magento\Framework package is skipped during compilation. If you want to make it injectable, you can fix it in your whole Project like that:

<virtualType name="Vendor\Package\Setup\Module\DataSetup" type="Magento\Setup\Module\DataSetup">
    <arguments>
        <argument name="context" xsi:type="object">Magento\Framework\Module\Setup\Context</argument>
    </arguments>
</virtualType>
<type name="Magento\Eav\Setup\EavSetup">
    <arguments>
        <argument name="setup" xsi:type="object">Vendor\Package\Setup\Module\DataSetup</argument>
    </arguments>
</type>

Now Magento will use the created virtual class when injecting DataSetup. This virtual class will already contain an instance of Setup\Context, so it does not need to inject it.

Hope this helps.

kassner commented 7 years ago

I get the same error when calling a custom CLI command. In the end, there was one class (not the Console Command directly, but one dependency of it) with the wrong __construct definition:

    public function __construct(
        AbstractManagement $manager,
        $options = [],
        ProductFactory $productFactory,
        DataConverterInterface $middleware = null
    ) {
        // ...
    }

As you can see, $options is defines a default value, but $productFactory right after doesn't. Although PHP lint doesn't complain about it, is quite a good practice to put arguments with default values in the end of the definition.

EDIT: Turns out is not just that, you need to delete var/generation and var/di after. The weird thing is that it works if you don't run setup:di:compile after.

PascalBrouwers commented 7 years ago

If it's coming from a 3rd party module, make sure they use the factory method. E.g. EavSetupFactory instead of EavSetup in the constructor.

timri commented 7 years ago

I have an similar issue, however not with Setup-classes but with thirdparty libraries. In my own module, I use a third party soapservice for synchronising values. This service needs WSAddressing, so I use the prezent/soap-client as dependency. I have custom classes for each of several soap-services with a common base class. So I have in my di.xml:

    <type name="MyVendor\MyModule\Soap\Client\Base">
        <arguments>
            <argument name="options" xsi:type="array">
                <item name="soap_version" xsi:type="const">SOAP_1_2</item>
                <item name="event_subscribers" xsi:type="array">
                    <item name="WSAddressing" xsi:type="object">Prezent\Soap\Client\Extension\WSAddressing</item>
                </item>
            </argument>
        </arguments>
    </type>
    <type name="Prezent\Soap\Client\Extension\WSAddressing">
        <arguments>
            <argument name="address" xsi:type="const">Prezent\Soap\Client\Extension\WSAddressing::ANONYMOUS</argument>
            <argument name="force" xsi:type="boolean">false</argument>
        </arguments>
    </type>

When I do NOT use setup:di:compile (or "rm var/di/*"), this works. Checking the di-config with magerun:

dev@shopserver:~/magento $ magerun2 config:data:di |grep -B5 -A5 'WSAddressing'
  "MyVendor\MyModule\Soap\Client\Base" => array:1 [
    "arguments" => array:1 [
      "options" => array:3 [
        "soap_version" => 2
        "event_subscribers" => array:1 [
          "WSAddressing" => array:1 [
            "instance" => "Prezent\Soap\Client\Extension\WSAddressing"
          ]
        ]
--
  "Prezent\Soap\Client\Extension\WSAddressing" => array:1 [
    "arguments" => array:2 [
      "address" => "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous"
      "force" => false
    ]
  ]

After I run "setup:di:compile", it reports:

$ magerun2 config:data:di |grep 'WSAddressing'
    "MyVendor\MyModule\Soap\Client\Base" => "a:2:{s:4:"wsdl";a:1:{s:4:"_vn_";b:1;}s:7:"options";a:1:{s:5:"_vac_";a:3:{s:12:"soap_version";i:2;s:17:"event_subscribers";a:1:{s:12:"WSAddressing";a:1:{s:3:"_i_";s:42:"Prezent\Soap\Client\Extension\WSAddressing";}}s:11:"locationMap";a:3:**redacted**}"
    "MyVendor\MyModule\Service\Customer\**redacted**" => "a:2:{s:7:"options";a:1:{s:5:"_vac_";a:3:{s:12:"soap_version";i:2;s:17:"event_subscribers";a:1:{s:12:"WSAddressing";a:1:{s:3:"_i_";s:42:"Prezent\Soap\Client\Extension\WSAddressing";}}s:11:"locationMap";a:3:{**redacted**}}"
    "MyVendor\MyModule\Service\ShipmentAddress\**redacted**" => "a:2:{s:7:"options";a:1:{s:5:"_vac_";a:3:{s:12:"soap_version";i:2;s:17:"event_subscribers";a:1:{s:12:"WSAddressing";a:1:{s:3:"_i_";s:42:"Prezent\Soap\Client\Extension\WSAddressing";}}s:11:"locationMap";a:3:{**redacted**}"
    "MyVendor\MyModule\Service\Contact\**redacted**" => "a:2:{s:7:"options";a:1:{s:5:"_vac_";a:3:{s:12:"soap_version";i:2;s:17:"event_subscribers";a:1:{s:12:"WSAddressing";a:1:{s:3:"_i_";s:42:"Prezent\Soap\Client\Extension\WSAddressing";}}s:11:"locationMap";a:3:**redacted**}}"
    "MyVendor\MyModule\Service\InboundCalcOrder\**redacted**" => "a:2:{s:7:"options";a:1:{s:5:"_vac_";a:3:{s:12:"soap_version";i:2;s:17:"event_subscribers";a:1:{s:12:"WSAddressing";a:1:{s:3:"_i_";s:42:"Prezent\Soap\Client\Extension\WSAddressing";}}s:11:"locationMap";a:3:{**redacted**}"

i.e. the options are handed down from the base-class to the individual classes, but the constructor-arguments for "Prezent\Soap\Client\Extension\WSAddressing" are missing. When I try to use the service, it fails with an exception "Error during soap.request event: Warning: DOMDocument::createElementNS() expects parameter 3 to be string, object given in /home/dev/magento/vendor/prezent/soap-client/src/Extension/WSAddressing.php", because $address contains the instance of the ObjectManager instead of an string.

I currently could work around this issue by not using DI to inject the event_subscriber and instead creating the object with new:

// in Soap\Client\Base::__construct
        if (!isset($options['event_subscribers'])) {
            $options['event_subscribers'] = [];
        }
        $options['event_subscribers']['WSAddressing'] = new \Prezent\Soap\Client\Extension\WSAddressing;

(actually no arguments are needed, the default-values work too. The constructor is actually:

    /**
     * Constructor
     *
     * @param string $address Reply-to address
     * @param bool $force Force WSA in non-WSDL mode
     */
    public function __construct($address = null, $force = false)
    {
        $this->address = $address;
        $this->wsaEnabled = $force;
    }

with "null" == WSAddress::ANONYMOUS internally, using that constant explicitly was a try to circumvent this issue)

magento-engcom-team commented 6 years ago

@webkulabhi, thank you for your report. We were not able to reproduce this issue by following the steps you provided. If you'd like to update it, please reopen the issue.