Local composer dependency in PHP and ClassNotFoundException

Composer makes working with PHP quite nice, but as with any package manager, you run into the occasional weird error message. Today I ran into a problem when adding a dependency to a project that was itself a local dependency to another project. I've been bitten by this a few times now, so here's a fix!

Here's what happened. The CMS I use fo this site is developed alongside this site, and included as a dependency to this site's project in composer.json, like this:

{
    "repositories": [
        {
            "type": "path",
            "url": "../babble"
        }
    ],
    "require": {
        "oal/babble": "*"
    }
}

So the CMS "Babble" is imported from the parent directory so that I can make changes to it without pushing a new version to Packagist. This works really well, but when I added a new dependency to Babble (in this case Spatie\ImageOptimizer), I got this exception:

Attempted to load class "OptimizerChainFactory" from namespace "Spatie\ImageOptimizer".

This exception kept getting thrown, even though I had run composer install, composer update and composer dump-autoload -o from both my site's project folder and the Babble project folder.

It made no sense - as far as I could see, all dependencies were in order!

I don't know why composer didn't pick this up, but the solution was rather simple: In my site's project directory (where the above composer.json file is), I deleted the composer.lock file, followed by another composer install.

> composer install
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 2 installs, 2 updates, 0 removals      
  - Installing spatie/image-optimizer (1.1.0): Downloading (100%)
  - Updating oal/babble (0.1.0 => 0.2.0): Symlinking from ../babble

Hurray! Now the composer project for my site finally detected that spatie/image-optimizer was added by the local oal/babble package.

All I needed to do after this was the usual composer dump-autoload -o and things were back in working order.

Let me know if this fixed your problem as well.