Database upgrade from OJS 3.2.1.2 to 3.3.0.6 failed (web): "Uncaught Error: Call to undefined method Application::initialize Database Connection()"

Dear all,

today I tried to upgrade OJS from version 3.2.1.2 to 3.3.0.6 and our database. I installed OJS 3.3.0.6 using the “Full Package” method and initiated the database upgrade using the Web/Browser method. Immediately after hitting the “Upgrade” button, the following error message appeared:

Fatal error: Uncaught Error: Call to undefined method Application::initializeDatabaseConnection() in /home/[foldername]/public_html/sys/lib/pkp/classes/install/form/UpgradeForm.inc.php:36 Stack trace: #0 /home/[foldername]/public_html/sys/lib/pkp/pages/install/InstallHandler.inc.php(106): UpgradeForm->execute() #1 /home/[foldername]/public_html/sys/lib/pkp/classes/core/PKPRouter.inc.php(391): InstallHandler->installUpgrade(Array, Object(Request)) #2 /home/[foldername]/public_html/sys/lib/pkp/classes/core/PKPPageRouter.inc.php(231): PKPRouter->_authorizeInitializeAndCallRequest(Array, Object(Request), Array, false) #3 /home/[foldername]/public_html/sys/lib/pkp/classes/core/Dispatcher.inc.php(143): PKPPageRouter->route(Object(Request)) #4 /home/[foldername]/public_html/sys/lib/pkp/classes/core/PKPApplication.inc.php(281): Dispatcher->dispatch(Object(Request)) #5 /home/[foldername]/public_html/sys/index.php(68): PKPApplication->execute() #6 {main} thrown in /home/[foldername]/public_html/sys/lib/pkp/classes/install/form/UpgradeForm.inc.php on line 36

Following this, I tried an upgrade to the previously released OJS version 3.3.0.5. Here the upgrade went through without errors, only some warnings occurred.

What could be the cause of this error? Are there any hints how I can fix it?

Thanks and best regards,
MIchael

Hi @adm_sub,

It looks like the code is incomplete. From where you downloaded the package?

Hi @Vitaliy,

I downloaded the current production release file OJS 3.3.0-6 (.tar.gz) from https://pkp.sfu.ca/ojs/ojs_download/

That’s strange. Can you take a look at the PKPApplication.inc.php file available at lib/pkp/classes/core starting from the app root and search for the declaration of initializeDatabaseConnection method? it should be on the line 187 of the file:

public function initializeDatabaseConnection() {

like here: pkp-lib/PKPApplication.inc.php at stable-3_3_0 · pkp/pkp-lib · GitHub

Dear @Vitaliy, thank you for looking into our problem.
I have just diffed the PKPApplication.inc.php file in our installation folder with the file on github. They are identical.
Here is the section where the function initializeDatabaseConnection is defined:

/**
	 * Initialize the database connection (and related systems)
	 */
	public function initializeDatabaseConnection() {
		// Ensure multiple calls to this function don't cause trouble
		static $databaseConnectionInitialized = false;
		if ($databaseConnectionInitialized) return;

		$databaseConnectionInitialized = true;
		$laravelContainer = new Illuminate\Container\Container();
		Registry::set('laravelContainer', $laravelContainer);
		(new Illuminate\Bus\BusServiceProvider($laravelContainer))->register();
		(new Illuminate\Events\EventServiceProvider($laravelContainer))->register();
		$eventDispatcher = new \Illuminate\Events\Dispatcher($laravelContainer);
		$laravelContainer->instance('Illuminate\Contracts\Events\Dispatcher', $eventDispatcher);
		$laravelContainer->instance('Illuminate\Contracts\Container\Container', $laravelContainer);

		// Map valid config options to Illuminate database drivers
		$driver = strtolower(Config::getVar('database', 'driver'));
		if (substr($driver, 0, 8) === 'postgres') {
			$driver = 'pgsql';
		} else {
			$driver = 'mysql';
		}

		$capsule = new Capsule;
		$capsule->addConnection([
			'driver'    => $driver,
			'host'      => Config::getVar('database', 'host'),
			'database'  => Config::getVar('database', 'name'),
			'username'  => Config::getVar('database', 'username'),
			'port'      => Config::getVar('database', 'port'),
			'unix_socket'=> Config::getVar('database', 'unix_socket'),
			'password'  => Config::getVar('database', 'password'),
			'charset'   => Config::getVar('i18n', 'connection_charset', 'utf8'),
			'collation' => Config::getVar('database', 'collation', 'utf8_general_ci'),
		]);
		$capsule->setEventDispatcher($eventDispatcher);
		$capsule->setAsGlobal();
		if (Config::getVar('database', 'debug')) Capsule::listen(function($query) {
			error_log("Database query\n$query->sql\n" . json_encode($query->bindings));//\n Bindings: " . print_r($query->bindings, true));
		});


		// Set up Laravel queue handling
		$laravelContainer->bind('exception.handler', function () {
			return new class implements Illuminate\Contracts\Debug\ExceptionHandler {
				public function shouldReport(Throwable $e) {
					return true;
				}

				public function report(Throwable $e) {
					error_log((string) $e);
				}

				public function render($request, Throwable $e) {
					return null;
				}

				public function renderForConsole($output, Throwable $e) {
					echo (string) $e;
				}
			};
		});

		$queue = new Illuminate\Queue\Capsule\Manager($laravelContainer);

		// Synchronous (immediate) queue
		$queue->addConnection(['driver' => 'sync']);

		// Persistent queue
		$connection = Capsule::schema()->getConnection();
		$resolver = new \Illuminate\Database\ConnectionResolver(['default' => $connection]);
		$manager = $queue->getQueueManager();
		$laravelContainer['queue'] = $queue->getQueueManager();
		$manager->addConnector('database', function () use ($resolver) {
			return new Illuminate\Queue\Connectors\DatabaseConnector($resolver);
		});
		$queue->addConnection([
			'driver' => 'database',
			'table' => 'jobs',
			'connection' => 'default',
			'queue' => 'default',
		], 'persistent');

		$queue->setAsGlobal();
	}

This part of the code looks normal to me. I’m wondering why the error says that the method is undefined if it’s definitely defined. Perhaps wrong object is returned in the call?

Can you specify what PHP version are you using?

Also, are you handy with debugging? As the message specifies, the error is thrown here: pkp-lib/UpgradeForm.inc.php at stable-3_3_0 · pkp/pkp-lib · GitHub. Application::get() should return an instance of Application class: ojs/Application.inc.php at main · pkp/ojs · GitHub, initializeDatabaseConnection method is inherited from the parent class - PKPApplicaiton, which it extends.