-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
The autoloader cache can keep an invalid entry for a class after an update #11290
Comments
So to summarize it shortly:
The actual fix is to restart apcu and kill the cache with that completely. Anyway, so the autoloader has a server/build/autoloaderchecker.sh Line 30 in 762002e
and add --apcu there is a diff on the autoloader:
without that, the apcuPrefix is never set and therefor the cache should never be used. So I had a look and tried to see where else this is set and found: Line 899 in fe21b10
The problem is, that our key does not change ever at all. Maybe instead it should be updated on version changes (of any app and the server (but that is too deep in the chain I think)) and additionally we should not set it at all for Since this is way to deeeeeeep down a wrong/unsafe road, I propose to revert #9442 for now, which newly introduced this for 14. |
@nickvergessen this is fixed then? |
This is fixed, but we should try to get it working properly to save filesystem checks etc |
Please update this issue, either to develop or close :) |
This issue has been automatically marked as stale because it has not had recent activity and seems to be missing some essential information. It will be closed if no further activity occurs. Thank you for your contributions. |
This is a corner case found during development; I do not know if it could happen in the real world or if the regular updater has means to prevent this (although #11225 looks similar), but in any case better have it documented.
In short, if a class that does not exist is queried it is stored as non-existent in the autoloader cache, but if the class is later introduced the cache still lists it as non-existent and thus the class can not be loaded. For the excruciatingly long explanation, see below ;-)
First, the steps to reproduce the problem:
git checkout v14.0.0 && git submodule update --recursive
git clone https://github.com/nextcloud/spreed
RoomShareProvider
was introduced withgit checkout 220726000^
docker run --rm --volume /PATH/TO/THE/NEXTCLOUD/GIT/DIRECTORY/:/var/www/html --volume /var/www/html/data --volume /var/www/html/config --publish 8000:80 --interactive --tty --name nextcloud-class-cache-bug nextcloudci/acceptance-php7.1:acceptance-php7.1-2
service apache2 start
docker exec -it nextcloud-class-cache-bug chown -R www-data:www-data /var/www/html/config /var/www/html/data
docker exec -it --user www-data nextcloud-class-cache-bug bash -c "cd /var/www/html && php occ maintenance:install --admin-pass=admin"
docker exec -it --user www-data nextcloud-class-cache-bug bash -c "cd /var/www/html && php occ app:enable spreed"
http://127.0.0.1:8000
and log in with useradmin
and passwordadmin
; you should see the Files appRoomShareProvider
is (implicitly) used in the constructor of the PageController of Talk withgit checkout fbe65943
If you then check the Nextcloud log you will see the following error message: OCP\AppFramework\QueryException: Could not resolve api! Class api does not exist. The exception is thrown when trying to instantiate the
PageController
but failing to instantiate one of its constructor parameters. However, although the message is correct, it is misleading in two different ways.When the
SimpleContainer
tries to get the constructor parameters it first tries to query the class name (if available) and, if that fails, then it tries to query the name of the parameter itself; the parameter that can not be instantiated isRoomController $api
, so although it is true that Class api does not exist the problem comes from not being able to instantiate RoomController in first place instead.However, the real problem is not in RoomController either; RoomController can not be instantiated because one of its constructor parameters can not be instantiated, and, in turn, that parameter can not be instantiated because one of its constructor parameters can not be instantiated because the class of the parameter,
RoomShareProvider
, is not found.In the above steps, if the container is started with Talk already in commit fbe65943 then
RoomShareProvider
can be found and everything works as expected. So, why isRoomShareProvider
not found if Talk is updated instead?If APCu is available (if installed, it is enabled by default), the main class loader of Nextcloud server tries to fetch classes from the cache when they are not found in its class map (like those in external apps without its own class loader). Therefore, the classes in Talk, like
OCA\Spreed\Share\RoomShareProvider
, are returned from the main autoloader cache if found there.If the class is not found then it is looked for it and the result is saved in the autoloader cache. However that is done in any case, even if the file is not found. And here comes the problem. In the above steps, when logging in for the first time the share provider factory queries the
RoomShareProvider
; it is not found, because in the Talk commit in which the server was started the class did not exist yet, and thus the class is stored as non-existent in the autoloader cache. However, that entry is not cleared after Talk is updated, so even if the PHP file now does exist it is still not found because it is marked as non-existent in the cache.As a final note it is worth pointing out that the problem does not occur if the server is started without enabling Talk and then Talk is enabled directly in the commit fbe65943. In theory, in that case
RoomShareProvider
would have been saved as non-existent too when logging in for the first time (although I have not actually verified it), but maybe the cache is cleared when an app is installed and thus the problem does not occur in that case; I have no idea :-)The text was updated successfully, but these errors were encountered: