Educating the world

Our blog has over 10,000 readers a month

log4j.properties made simple

May 23rd, 2015

I wrote a huge article titled "Configuring log4j.properties" on, funnily enough, how to configure Log4J but sometimes it still isn't as good as great example:

log4j.rootLogger = INFO, X
log4j.logger.A.B.C=ALL, X
# or this for custom logger log4j.logger.A.B.C=A.B.C.MyLogger

#set the appender named X to be a console appender
log4j.appender.X=org.apache.log4j.ConsoleAppender

#set the layout for the appender X
log4j.appender.X.layout=org.apache.log4j.PatternLayout
log4j.appender.X.layout.conversionPattern=%m%n

#log4j.logger.A.B.C.appender= blar...

[ With the help of http://www.java2s.com/Code/Java/Language-Basics/Examplelog4jConfigurationFile.htm ]

Eclipse plugins

March 4th, 2015

I'm constantly trying new versions of Eclipse. I tend to be a fresh-install-reinstall-plugins kind of guy rather than a check-for-updates kind of guy. There always seems less that can go wrong when you reinstall everything from scratch each time, plus it's a chance to clean out all those temp folders. Of course there are a few drawbacks like having to keep tweaking your configuration settings but over all I prefer it this way.

The locations of plugins are the main things that I need to remember. Some versions of Eclipse come without the Market Place which is now itself a plugin! So I'm creating this blog to help me remember all the plugins I like to use.

Start Explorer - opens file manager or shell at package explorer level
http://basti1302.github.com/startexplorer/update/

PMD - a bit like lint
https://sourceforge.net/projects/pmd/files/pmd-eclipse/update-site/

ECL Emma - code coverage
http://update.eclemma.org/

Yii Migration Tool No such file or directory

February 10th, 2015

I develop under Windows when I'm and home and in the office but when I'm at out and about I develop on my Mac Book Pro. While both run XAMPP, I recently came across a difference between the Windows and Mac versions while I was using Yii2 Framework (but I understand that this happens while using Yii1 too).

The problem manifests itself with the following Exception message from the Yii Connection class:

Yii Migration Tool (based on Yii v2.0.2)

Exception 'yii\db\Exception' with message 'SQLSTATE[HY000] [2002] No such file or directory'

in /Applications/XAMPP/xamppfiles/htdocs/rfc/yii-application/vendor/yiisoft/yii2/db/Connection.php:539

Stack trace:
#0 /Applications/XAMPP/xamppfiles/htdocs/rfc/yii-application/vendor/yiisoft/yii2/db/Connection.php(846): yii\db\Connection->open()
#1 /Applications/XAMPP/xamppfiles/htdocs/rfc/yii-application/vendor/yiisoft/yii2/db/Connection.php(833): yii\db\Connection->getMasterPdo()
#2 /Applications/XAMPP/xamppfiles/htdocs/rfc/yii-application/vendor/yiisoft/yii2/db/Command.php(208): yii\db\Connection->getSlavePdo()
#3 /Applications/XAMPP/xamppfiles/htdocs/rfc/yii-application/vendor/yiisoft/yii2/db/Command.php(815): yii\db\Command->prepare(true)
#4 /Applications/XAMPP/xamppfiles/htdocs/rfc/yii-application/vendor/yiisoft/yii2/db/Command.php(350): yii\db\Command->queryInternal('fetchAll', NULL)
#5 /Applications/XAMPP/xamppfiles/htdocs/rfc/yii-application/vendor/yiisoft/yii2/db/mysql/Schema.php(198): yii\db\Command->queryAll()
#6 /Applications/XAMPP/xamppfiles/htdocs/rfc/yii-application/vendor/yiisoft/yii2/db/mysql/Schema.php(97): yii\db\mysql\Schema->findColumns(Object(yii\db\TableSchema))
#7 /Applications/XAMPP/xamppfiles/htdocs/rfc/yii-application/vendor/yiisoft/yii2/db/Schema.php(139): yii\db\mysql\Schema->loadTableSchema('migration')
#8 /Applications/XAMPP/xamppfiles/htdocs/rfc/yii-application/vendor/yiisoft/yii2/console/controllers/MigrateController.php(126): yii\db\Schema->getTableSchema('{{%migration}}', true)
#9 /Applications/XAMPP/xamppfiles/htdocs/rfc/yii-application/vendor/yiisoft/yii2/console/controllers/BaseMigrateController.php(607): yii\console\controllers\MigrateController->getMigrationHistory(NULL)
#10 /Applications/XAMPP/xamppfiles/htdocs/rfc/yii-application/vendor/yiisoft/yii2/console/controllers/BaseMigrateController.php(99): yii\console\controllers\BaseMigrateController->getNewMigrations()
#11 [internal function]: yii\console\controllers\BaseMigrateController->actionUp(0)
#12 /Applications/XAMPP/xamppfiles/htdocs/rfc/yii-application/vendor/yiisoft/yii2/base/InlineAction.php(55): call_user_func_array(Array, Array)
#13 /Applications/XAMPP/xamppfiles/htdocs/rfc/yii-application/vendor/yiisoft/yii2/base/Controller.php(151): yii\base\InlineAction->runWithParams(Array)
#14 /Applications/XAMPP/xamppfiles/htdocs/rfc/yii-application/vendor/yiisoft/yii2/console/Controller.php(91): yii\base\Controller->runAction('', Array)
#15 /Applications/XAMPP/xamppfiles/htdocs/rfc/yii-application/vendor/yiisoft/yii2/base/Module.php(455): yii\console\Controller->runAction('', Array)
#16 /Applications/XAMPP/xamppfiles/htdocs/rfc/yii-application/vendor/yiisoft/yii2/console/Application.php(161): yii\base\Module->runAction('migrate', Array)
#17 /Applications/XAMPP/xamppfiles/htdocs/rfc/yii-application/vendor/yiisoft/yii2/console/Application.php(137): yii\console\Application->runAction('migrate', Array)
#18 /Applications/XAMPP/xamppfiles/htdocs/rfc/yii-application/vendor/yiisoft/yii2/base/Application.php(375): yii\console\Application->handleRequest(Object(yii\console\Request))
#19 /Applications/XAMPP/xamppfiles/htdocs/rfc/yii-application/yii(31): yii\base\Application->run()
#20 {main}

When connecting to MySQL on a Mac (or a unix box) if you specify host as "localhost" MySQL switches the transport to use file system sockets instead of using a network socket. There are lots of reasons to do this, security and efficiency are the main ones. There is almost no code difference to using a socket on the file system and a socket in the kernel because unix treats them both as file descriptors. Windows treats everything differently and so there is no concept of a file base socket. Windows just uses normal network sockets with all the overhead and security concerns that has.

There are 2 ways you can solve this issue. The first and simplest way to fix this problem is to not use "localhost" in your DSN string. If you use the loopback IP address (127.0.0.1) then MySQL will force itself to use a real network socket in the same way that it would under Windows. So in our Yii2 example, just change the DSN configuration held in: yii2_root/common/config/main-local.php to:

return [
    'components' => [
        'db' => [
            'class' => 'yii\db\Connection',
            //'dsn' => 'mysql:host=localhost;dbname=rfc',
            'dsn' => 'mysql:host=127.0.0.1;dbname=rfc',
            'username' => 'root',
            'password' => '',
            'charset' => 'utf8',
        ],
        'mailer' => [
        ....

The second way of solving this problem is still quite simple but everything around it is complicated!

The reason why it is happening is because MySQL can not find the "socket" file (as we said earlier), but all the configuration seems to indicate that everything is ok. To cut hours of investigation short and to put yourself out of misery, there are 2 versions of PHP running on your Mac with 2 configurations. As a consequence your Yii installation is using the wrong one (i.e. the command line one and not your XAMPP installation).

When you run your Yii application through your web browser you are running your XAMPP's version of PHP which is why when you look at the phpinfo() via a web page everything looks all right. PHP shows version 5.6.3, the "Loaded Configuration File" is /Applications/XAMPP/xamppfiles/etc/php.ini and the Configure Command clearly shows --with-mysql-sock=/Applications/XAMPP/xamppfiles/var/mysql/mysql.sock, and that file exists.

However when you run php from the command line the shell runs through your path and finds a version of php located in /usr/bin. When you issue the command php --ini to find out which configuration file is being read you get the following back:

Configuration File (php.ini) Path: /etc
Loaded Configuration File:         (none)
Scan for additional .ini files in: /Library/Server/Web/Config/php
Additional .ini files parsed:      (none)

Inspecting the /etc path you will not find a php.ini. No file means you will get the default configuration. If you issue a command line based php with the -i option you will see the following configuration instead: PHP shows version 5.5.14, the "Loaded Configuration File" is (none) and the Configure Command shows "--with-mysql-sock=/var/mysql/mysql.sock"

To fix this you must change the yii application program to use the correct version of php. Modifiy yii2_root/yii and change the env under which it runs from:

#!/usr/bin/env php

to

#!/usr/bin/env /Applications/XAMPP/xamppfiles/bin/php

Using XAMPP's version of PHP will mean you can keep your localhost in the DNS and MySQL will use sockets on your production servers instead of the 127.0.0.1. Forcing your application to open sockets on the localhost will mean that your firewall configuration will need extra rules and configuration to prevent traffic coming from an external port and bouncing off an internal port in order to talk to a localhost socket. Using file domain sockets will just mean making sure that the correct file permissions are set on the socket file so that only the MySQL process can talk to it.

Checking if you are on the homepage

January 30th, 2015

The way to reference the default controller and the default action on that controller has changed. Essentially the defaultController in Yii might not be a controller, so it is now referred to as a route (i.e. defaultRoute) and the default Action on a controller in Yii2 is the name of the action rather than the Action object.

Yii

PHP

$controller Yii::app()->getController();
$default_controller Yii::app()->defaultController;
$isHome = (($controller->id === $default_controller->id) && ($controller->action->id === $controller->defaultAction->id)) ? true false;

Yii2

PHP

$controller Yii::$app->controller;
$default_controller Yii::$app->defaultRoute;
$isHome = (($controller->id === $default_controller) && ($controller->action->id === $controller->defaultAction)) ? true false;

Reference: http://stackoverflow.com/questions/12341791/yii-check-if-homepage

Yii to Yii2

January 30th, 2015

The Yii Framework has had a new major release and while the API documentation for the new version 2 is a lot better, there doesn't seem to be an easy way to find out what the new way of doing something is. I'm setting this article up as blogglue in order to join all these helper articles together.