Injectable Logger with CDI

In my Java EE projects I don’t like logger configuration in every classes such as below:

private Logger logger = Logger.getLogger(this.getClass().getName());

I want to use with @Inject annotation. Fortunately there is @Produces annotation for it (see CDI – JSR 299: Context and Dependency Injection). I’m writing a producer class then I can @Inject logger  everywhere as below:

package com.devsniper.demoapp.util;

import javax.enterprise.inject.Produces;
import javax.enterprise.inject.spi.InjectionPoint;

import org.apache.log4j.Logger;

/**
 * Logging producer for injectable log4j logger
 *
 * @author cem ikta
 */
public class LoggerProducer {
   /**
    * @param injectionPoint
    * @return logger
    */
    @Produces
    public Logger produceLogger(InjectionPoint injectionPoint) {
		return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName());
    }
}

in classes:

@Inject
private transient Logger logger;

I am using log4j in producer class but this works well for java logger too. Transient keyword is important, without transient keyword you get the following error in GlassFish:

WELD-000054 Producers cannot produce non-serializable instances for injection into non-transient fields of passivating beans\\n\\nProducer\: Producer Method [Logger] with qualifiers [@Any @Default] declared as [[method] @Produces public  com.devsniper.demoapp.util.LoggerProducer.produceLogger(InjectionPoint)]\\nInjection Point\: [field] @Inject private com.desniper.demoapp.controller.UserController.logger

How to update sun jdk 7 on Ubuntu 12.04

java logo

Oracle has released  JDK 7 Update 6 with JavaFX 2.2 Final for GNU/Linux, Mac OS X and MS Windows last week. I have already written how to install Sun JDK 6-7 on Ubuntu 12.04. I want to write how to update JDK 7 Update 6 manually.

Update JDK 7u6:

If you want to manually upgrade to a new version, first uninstall the JDK 7 and then reinstall. You can check your java version in console "java -version” or online here: Verify java version

Package manager: Those who have already installed an older version of Sun Java via the package manager, removes the same way.

  • First, close the web browser (because of java browser plugin).
  • Remove the Java version from the alternatives system:
sudo update-alternatives --remove "javac" "/usr/lib/jvm/jdk1.7.0_04/bin/javac"
sudo update-alternatives --remove "java" "/usr/lib/jvm/jdk1.7.0_04/bin/java"
sudo update-alternatives --remove "javaws" "/usr/lib/jvm/jdk1.7.0_04/bin/javaws"
  • Remove the browser plugin link:
sudo rm /usr/lib/mozilla/plugins/libnpjp2.so
  • Remove the jdk directory:
sudo rm -rf /usr/lib/jvm/jdk1.7.0_04

Netbeans note: If you uninstall old JDK, NetBeans 7.2 is not starting. Open the netbeans.conf file under etc directory and change the netbeans_jdkhome parameter to the new jdk path.

netbeans_jdkhome="/usr/lib/jvm/jdk1.7.0_06"

Happy coding.

Internationalisation tips for Java and JavaFX

flags

java logo

Java internationalisation (i18n) tips:

I do not like large Resource Bundle files when I write multi-language desktop applications in Swing or JavaFX. So I wanted to use a resource file for each module in my applications. I’ve written a util class  with enum as below. Now I can use this utility from anywhere.

package com.devsniper.lagoserp.util;

import java.util.MissingResourceException;
import java.util.ResourceBundle;

/**
 * Resource Bundle helper.
 * Each module has its own resource bundle file for i18n strings.
 * Always read default locale from Locale.getDefault().
 *
 *
 * Use of I18n:
 * 
 *      I18n.MODULE_NAME.getString("stringKey");
 * 
 *
 * @see ResourceBundle
 *
 * @author cem ikta
 */
public enum I18n {
    // module with resource files
    COMMON("com.devsniper.demoapp.resources.i18n.common"),
    CUSTOMER("com.devsniper.demoapp.resources.i18n.customer"),
    INVOICE("com.devsniper.demoapp.resources.i18n.invoice");

    private ResourceBundle resourceBundle;

    I18n(String bundleFile) {
        resourceBundle = ResourceBundle.getBundle(bundleFile);
    }

    /**
     * Gets a string for the given key from resource bundle.
     *
     * @param key the key for the desired string
     * @return the string for the given key
     */
    public String getString(String key) {
        try {
            return resourceBundle.getString(key);
        } catch (MissingResourceException e) {
            System.err.println(e);

            return "err#";
        }
    }
}

Call to use only I18n.MODULE.getString(“stringKey”)
I have two ResourceBundles common.properties for English and common_de_DE.properties for German.

// set default locale english
Locale.setDefault(new Locale("en", "EN"));
// set default locale for German
// Locale.setDefault(new Locale("de", "DE"));
AppView appView = new AppView();
appView.setTitle(I18n.COMMON.getString("app.title"));