Set up logging in a Java webapplication

There’s a lot of sources on the net for configuring and using the different logging frameworks in Java, so i’m just going to show you how you can use an listener for initializing a Log4J configuration in an Web application.

Put the listener-init in your web.xml

 <context-param>
        <param-name>log4jConfigLocation</param-name>
        <param-value>log4j-frontend.xml</param-value>
    </context-param>
    <listener>
        <listener-class>
            se.lif.www.site.Log4jConfigListener
        </listener-class>
    </listener>

The listener (also using Apache Commons ConfigurationUtils)

public class Log4jConfigListener implements ServletContextListener {

    @Override
    public void contextInitialized(ServletContextEvent sce) {
        URL configUrl = null;

        ServletContext servletContext = sce.getServletContext();
        String log4jConfigName = servletContext.getInitParameter("log4jConfigLocation");

        // Try to locate file in classpath
        configUrl = ConfigurationUtils.locate(log4jConfigName);

        if (configUrl != null) {
            //if the location is other than the root
            DOMConfigurator.configure(configUrl.getPath());
        }
    }

    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        //cleanup or be forever silent
    }
}

and that should be it!

Some other things of usage when logging:

  • If you run with ”-Dlog4j.debug” then log4j will print out info to standard output telling how it is trying to configure itself. Looking through that will tell you where it is looking for the config file.
  • And Please, do use SLF4J even if you use Log4J (or another logging framwork) for your logging. It’s a drop-in replacement for many logging frameworks with too many benefits to write about here.
  • Static or new instance’s for your loggers? The pattern for getting a logger is usually like this:
package some.package;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyClass {
       final (static) Logger logger = LoggerFactory.getLogger(MyClass.class);
... etc
}

but some argue that you should make new instances. SLF4J has an little interesting read, and recommends static.

Oh, BTW, here’s an alternative way to do the same as in this post, but without a listener.

Generating pseudorandom numbers in Java

I had a closer look at generating pseudorandom numbers in Java the other day. Mainly nailing the difference between using Math,random, new Random() or (since Java 7) ThreadLocalRandom. Enjoy the little example, (and if i did something wrong, please correct me in the comments).


package com.funstuff.javapractices.commontasks;

import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;

/**
 * Examples of different ways to run random.
 *
 * This shows 3 different ways of generating a basic pseudorandomnumber in
 * Java.
 *
 * 

* Using: Math.random, new Random and ThreadLocalRandom * *

* Math.random uses Random.nextDouble() underneath the hood; Random.nextDouble * is not as efficient as for example Random.nextInt * http://stackoverflow.com/questions/738629/math-random-versus-random-nextintint * * Math.random() uses a single static java.util.Random instance, which itself is * thread-safe? This can generate contention- if you have multiple threads * that are supposed to run in parallel, through Math.random() they will all * compete for its lock and can deteriorate into running serially. * *

* The Random object has different utility methods, and by default gets it's * seed from the systemtime. It has constructor that let's you set your own * seed. As this is pseudorandom algorithms - If you initialize multiple Random * objects with the same seed they'll generate the same numbersequence. * *

* * From the javadocs: "the concurrent use of the same java.util.Random * instance across threads may encounter contention and consequent poor * performance. Consider instead using ThreadLocalRandom in multithreaded * designs." * * With java 7 comes ThreadLocalRandom in the java.util.concurrency package * (wich extends java.util.Random) Characteristics is that it prohibits setSeed * (gives UnsupportedOperationException), it's static and it's threadlocal. And while * Math.random() works on a static singleton instance of Random, * ThreadLocalRandom works on a thread local instance. See * http://niklasschlimm.blogspot.se/2012/01/java-7-how-to-write-really-fast-java.html * for a good and deep explanation. * * * * * @author whatever whatever */ public final class RandomNumbers { private static int loopCtr = 10000; private static long startTime; private static long endTime; public static void main(String... args) { System.out.println(System.lineSeparator()); mathRandom(); newRandom(); threadLocalRandom(); System.out.println(System.lineSeparator()); //raise the stakes.. loopCtr = 1600000; mathRandom(); newRandom(); threadLocalRandom(); System.out.println(System.lineSeparator()); //just a range example newRandomWithRange(); } private static void mathRandom() { startTime = System.currentTimeMillis(); for (int i = 0; i < loopCtr; i++) { ////gives a double between 0.0 and less than 1.0 //but often seen used like this ( here to give a number between 1 and 10) long mathRandomDoubleRounded = Math.round(Math.random() * 10); } endTime = System.currentTimeMillis(); System.out.println("Total execution time: " + (endTime - startTime) + "ms"); } private static void newRandom() { startTime = System.currentTimeMillis(); Random random = new Random(); for (int i = 0; i < loopCtr; i++) { double randomDouble = random.nextDouble(); } endTime = System.currentTimeMillis(); System.out.println("Total execution time: " + (endTime - startTime) + "ms"); } private static void newRandomWithRange() { //random x between 0 and less than 11 - (Remember Java usually handles ranges like [inclusive, exclusive]) //and to get a range, just add the MIN of your range .i.e //we want something between 10 and 17, and init with (MAX-MIN)+1 int min = 10; int max = 17; Random random = new Random(); int randomValue = (random.nextInt((max - min) + 1) + min); System.out.println("RandomValue:" + randomValue); } private static void threadLocalRandom() { startTime = System.currentTimeMillis(); for (int i = 0; i < loopCtr; i++) { double threadLocalRandom = ThreadLocalRandom.current().nextDouble(); } endTime = System.currentTimeMillis(); System.out.println("Total execution time: " + (endTime - startTime) + "ms"); } }

See this blog for digging deeper!.

1Z0-895 ( Java EE 6 EJB Developer Certified Expert Exam )

I just passed the  the EJB SCBCD/OCPJBCD  exam with 86%. I’m happy with that!
Tools for passing the exam were:
* Mannings EJB in action Book
* O’Reillys EJB 3.1 Book
* Parts of JEE6 tutorial
* Enthuwares testexams. Recommended
*The notes found in the link section for certifications on coderanch , thanks Ivan and Fritz, Very good!!
* and… some coding and testing and coding and testing and… yes, you get it.

I worked a bit with EJB before, and will continue to do so. Next book for me is Adam Biens Enterprise patterns, but first… a well deserved rest

Got Java properties

Some notes on Javaproperties that i gathered from different sources (thanks btw)

Java Properties:

* Properties can be saved to a stream or loaded from a stream.
* Each key and its corresponding value in the property list is a string.
* Properties inherits from Hashtable, the put and putAll methods can be applied to a Properties object. Their use is strongly discouraged as they allow the caller to insert entries whose keys or values are not Strings. The setProperty method should be used instead.
* Properties use ISO 8859-1 character encoding. Unicode escapes can be used; however, only a single ‘u’ character is allowed in an escape sequence. The native2ascii tool can be used to convert property files to and from other character encodings.
* Generally properties should be read by classpath, not by file.

Example of syntax in propertiesfile!

# You are reading the ”.properties” entry.
! The exclamation mark can also mark text as comments.
website = http://www.eff.org
language = English
# The backslash below tells the application to continue reading
# the value onto the next line.
message = Welcome to \
Wikipedia!
# Add spaces to the key
key\ with\ spaces = This is the value that could be looked up with the key ”key with spaces”.
# Unicode
tab : \u0009

How to read properties file in web application?

In a webapplication you don’t wan’t to use the current working directory i.e. /home/Tomcat/bin or something different, but thus not home/Tomcat/webapps/contextname as you would like. (Too see current working directory: System.out.println(new File(”.”).getAbsolutePath()));

However, if still using file-related properties loading use absolute paths. E.g. /full/path/to/file.ext.

Note: Paths in Java
absolute like “/full/path/to/file..xml”;
relative like “path/resource.xml”;

Relative means, relative to the location, where the method was called. The path will be appended if needed.. Absolute will be used as is, only first / will be removed before the search.

In a WAR and etc, The normal practice is to place those kind of resources in the classpath, or to add its full path to the classpath (in an IDE like Eclipse that’s the src folder and the ”build path” respectively). This way you can grab them with help of the ClassLoader by ClassLoader#getResource() or ClassLoader#getResourceAsStream(). It is able to locate files relative to the ”root” of the classpath. In webapplications (or any other application which uses multiple classloaders) it’s recommend to use the ClassLoader as returned by Thread.currentThread().getContextClassLoader() for this, ie ClassLoader classLoader = Thread.currentThread().getContextClassLoader();

This returns the parentmost classloader which has access to all resources. The MyService.class.getClassLoader() will only return the (child) classloader of the class in question which may not per se have access to the desired resource. It will always work in environments with a single classloader, but not always in environments with a complex hierarchy of classloaders like webapps.

MyService.class.getClassLoader().getResourceAsStream(”/p.properties”);
In Thread#getContextClassLoader(), remove the leading /.

getResourceAsStream() will load a file path relative from your application’s classpath.

Another alternative in webapps is the ServletContext#getResource() and its counterpart ServletContext#getResourceAsStream(). It is able to access files located in the public web folder of the webapp project, including the /WEB-INF folder. The ServletContext is available in servlets by the inherited getServletContext() method.

Class.getResourceAsStream() method or the ClassLoader.getResourceAsStream() method?

There are ClassLoader.getResource() and Class.getResource() and they work differently!!!

java docu:

The methods in ClassLoader use the given String as the name of the
resource without applying any absolute/relative transformation (cf. the
methods in Class). The name should not have a leading “/”.

Using getClass().getResourceAsStream(”pos_config.properties”) is dangerous because you’re using a path that’s resolved relative to the given class, and a subclass could change the location against which it’s resolved. Therefore, it’s safest to name an absolute path within the jar:

Foo.class.getResourceAsStream(”/config.properties”)
Foo.class.getClassLoader().getResourceAsStream(”config.properties”)

getResourceAsStream() method or the getResource() method?

getResourceStream uses getResource underneath the hood.

3 Choices:

Put it in the classpath, load it by ClassLoader#getResourceAsStream() with a classpath-relative path:

Properties properties = new Properties();
properties.load(Thread.currentThread().getContextClassLoader().getResourceAsStream(”filename.properties”));

Here filename.properties is supposed to be placed in one of the roots which are covered by the default classpath of a webapp, e.g. Webapp/WEB-INF/lib, Webapp/WEB-INF/classes, Appserver/lib or JRE/lib. If the propertiesfile is webapp-specific, best is to place it in WEB-INF/classes. If you’re developing a project in an IDE, you can also drop it in src folder (the project’s source folder).

Put it somewhere outside the default classpath and add its path to the classpath of the appserver. In for example Tomcat you can configure it as shared.loader property of Tomcat/conf/catalina.properties.

Put it somewhere in web folder (the project’s web content folder), so that you can load it by ServletContext#getResourceAsStream() with a webcontent-relative path:

Properties properties = new Properties();
properties.load(getServletContext().getResourceAsStream(”/WEB-INF/filename.properties”));

Note that I have demonstrated to place the file in /WEB-INF folder, otherwise it would have been public accessible by any webbrowser. Also note that the ServletContext is in any HttpServlet class just accessible by the inherited GenericServlet#getServletContext().

Put it somewhere in local disk file system so that you can load it the usual java.io way with an absolute local disk file system path:

Properties properties = new Properties();
properties.load(new FileInputStream(”/absolute/path/to/filename.properties”);

I personally prefer putting it in the classpath outside the project (add new path to the classpath), so that I can manage it from outside and so I don’t need to hardcode an absolute disk file system path in my Java code.

How to convert properties file into XML file?

java.util.Properties class come with a storeToXML() method to convert existing properties data into a XML file.

Slashes?

props.setProperty(”test”, ”C:/dev/sdk/test.dat”); Use forward slashes (or \\ or \u005c) even on Windows but rember some occasions on Windows must have backlashes – ie NTLM login where there exists DOMAIN\USERNAME

How to read properties file placed outside war?

Provide the file name using context param or java system parameter.

1.Context Param

daofilename
D:\daofilename.props

2.System Parameter

java -Ddao.filename=D:\daofilename.props server and String propPath = System.getProperty( ”my.app.properties” );

ou should give property file location as java runtime property to your web container..

Such as, java -DmypropertyFile.location=c:/propertyfile.properties -jar yourContainer.jar

If you are using Tomcat you can add any properties you like to the context, look at the documentation for context.xml. All the application servers has their own way of doing this…

Or use JNDI-resources

Apache Commons has a Library Called Apache Commons Configuration , check it out.

Read
http://www.javaworld.com/javaworld/javaqa/2003-08/01-qa-0808-property.html
http://www.thinkplexx.com/learn/howto/java/system/java-resource-loading-explained-absolute-and-relative-names-difference-between-classloader-and-class-resource-loading
http://stackoverflow.com/questions/6608795/what-is-the-difference-between-class-getresource-and-classloader-getresource
http://www.javaworld.com/javaworld/javaqa/2002-11/02-qa-1122-resources.html
http://viralpatel.net/blogs/2009/10/loading-java-properties-files.html
http://www.eclipsezone.com/eclipse/forums/t101557.html

Installera Oracle Java JDK 7 i Ubuntu

Om man till exempel vill prova JavaFX 2.0 behöver man för tillfället installera en fräschare JDK än den 1.7 Open JDK som ingår i Ubuntu. Det kan vara lite lurigt att hämta senaste Oracle-versionen (i skrivande stund 1.7. u2) då Oracle inte bjuder på ett färdigt .deb paket. Fear not, det finns en PPA som fixar jobbet åt dig! Kör följande i terminalen:

sudo add-apt-repository ppa:webupd8team/java 
sudo apt-get update sudo mkdir -p /usr/lib/mozilla/plugins #bara i fall att
 sudo apt-get install oracle-jdk7-installer 
Vill du sedan avinstallera Oracle JDK kör du: 
sudo apt-get remove oracle-jdk7-installer
Glöm inte att ändra vilken version av JVM du ska använda som
 default (update-alternatives osv) 
 

Java JDK 5 på Ubuntu 10.10

Jag behövde nyligen en äldre version av Java JDK för ett äldre projekt. Då man ersatt det med nyare Java (6) i nyare versioner av Ubuntu fick jag hämta det från ett äldre repo. Om någon annan behöver JDK 5 i Ubuntu 10.10 så tänkte jag dela med mig av det.

1. Öppna ”programcentral för ubuntu” under programmenyn. Välj ”redigera” samt ”programkällor”
2. Under ”övrig programvara” lägg till ” deb http://ir.archive.ubuntu.com/ubuntu jaunty-updates main multiverse”

Det är en äldre Ubuntu-versions repo vi lägger till (jauntys)

3. stäng och välj att antingen leta reda på ”sun-java5-jdk” i programcentralen, eller kör
sudo aptitude update
sudo aptitude install sun-java5-jdk

i terminalen.

För att sedan välja vilken java-version som ska vara den aktuella, om du har flera installade,kör

update-alternatives –config java
i terminal.