utility

Unable to Delete Dist Folder from Netbeans’ Build.xml File

I found this weird error when building my java application into jar from Netbeans, somehow Netbeans shows error due to unreadable dist folder. And the weird thing is, i cannot delete the dist folder manually, it keeps giving me the Folder Access Denied dialog box with choices to “Try Again” or “Cancel”. I also have tried changing permissions in the properties window but it does not seem to work.

Well the workaround is actually simple, i just open task manager, and end explorer.exe process. And i dont know why, but my dist folder is gone. Very weird actually 😀

How to Add Expiry Date on Your Static Files using Java’s Servlet Filter

Perhaps there would be some people wondering, why should i use expiry date on my static files? Well for a first-time visitor to your page may have to make several HTTP requests to load all your web page’s content, but by using the Expires header you make those components cacheable. This avoids unnecessary HTTP requests on subsequent page views. Expires headers are most often used with images, but they should be used on all components including scripts, stylesheets, and Flash components.

But dont forget, using a far future Expires header affects page views only after a user has already visited your site. It has no effect on the number of HTTP requests when a user visits your site for the first time and the browser’s cache is empty. Therefore the impact of this performance improvement depends on how often users hit your pages with a primed cache.

Okay, so basically i use a simple ServletFilter to add Expiry header on each static contents, on this example would be .css, .png and .gif files. So here is my code,

package com.edw.fw.server.filter;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

public class ExpiryFilter implements Filter {

	// add a five years expiry
	private Integer years = 5;

	@Override
	public void destroy() {
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		if (years > -1) {
			Calendar c = Calendar.getInstance();
			c.setTime(new Date());
			c.add(Calendar.YEAR, years);

			// HTTP header date format: Thu, 01 Dec 1994 16:00:00 GMT
			String o = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss zzz")
					.format(c.getTime());
			((HttpServletResponse) response).setHeader("Expires", o);
		}

		chain.doFilter(request, response);
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {		
	}
}

And dont forget to register your Filter to your web.xml file

		<!--  
			expiration date filter
		-->
	  	<filter>
			<description>Set cache expiry for static content</description>
			<filter-name>ExpiryFilter</filter-name>
			<filter-class>com.edw.fw.server.filter.ExpiryFilter</filter-class>
		</filter>
		<filter-mapping>
			<filter-name>ExpiryFilter</filter-name>
			<url-pattern>*.css</url-pattern>
			<dispatcher>REQUEST</dispatcher>
		</filter-mapping>
		<filter-mapping>
			<filter-name>ExpiryFilter</filter-name>
			<url-pattern>*.png</url-pattern>
			<dispatcher>REQUEST</dispatcher>
		</filter-mapping>
		<filter-mapping>
			<filter-name>ExpiryFilter</filter-name>
			<url-pattern>*.gif</url-pattern>
			<dispatcher>REQUEST</dispatcher>
		</filter-mapping>

This is what it looks like on my browser’s http log,

as you can see, my http request get 304 not modified header, due to accessing my browser’s cache instead of the targetted web page.

Okay, i hope this helped other. Have Fun 🙂

A Weird Exception, java.lang.IllegalArgumentException: Filter mapping specifies an unknown filter name “FilterName”

Today i found an exception while deploying my .war application to Tomcat web server for production usage, very weird because i never had this exception on my IDE before. This is the complete exception stacktrace,

Caused by: java.lang.IllegalArgumentException: Filter mapping specifies an unknown filter name FilterName
	at org.apache.catalina.core.StandardContext.addFilterMap(StandardContext.java:2506)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.lang.reflect.Method.invoke(Unknown Source)

below is my web.xml content,

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="crm" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_4.xsd">
    <display-name>edw</display-name>
    <context-param>
        <param-name>edw</param-name>
        <param-value>edw</param-value>
    </context-param>
    
    <filter-mapping>
        <filter-name>FilterName</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
	
    <filter>
        <filter-name>FilterName</filter-name>
        <filter-class>com.edw.filter.FilterName</filter-class>
    </filter>
</web-app>

How to fix it is actually very simple, i only need to swap between and tag. Below is the correct web.xml.

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="crm" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_4.xsd">
    <display-name>edw</display-name>
    <context-param>
        <param-name>edw</param-name>
        <param-value>edw</param-value>
    </context-param>
    
    <filter>
        <filter-name>FilterName</filter-name>
        <filter-class>com.edw.filter.FilterName</filter-class>
    </filter>

    <filter-mapping>
        <filter-name>FilterName</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

</web-app>

Weird eh :p

How to Compress Log4J’s Log File

Today i found a very weird condition on one of my end user. Their application’s log file is so big, despite the log4j’s log level is set to INFO. Im using log4j’s DailyRollingFileAppender which would create a new log file everyday. Each file’s size is around 10 to 20MB, and i see the log files is like 3 months old. Which makes total of almost 2GBs of log files.

So my solution to them is to compress everyday’s log into gzip, gz or perhaps into zip file. Basically, im using one of log4j’s companion..

Okay, so here is my solution, first a simple pom.xml to download the libraries needed,

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.edw.compresslogfile</groupId>
    <artifactId>CompressLogFile</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>CompressLogFile</name>
    <url>http://maven.apache.org</url>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>apache-log4j-extras</artifactId>
            <version>1.0</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>                        
    </dependencies>
</project>

And then my log4j.properties file, please take a look at line 7. It will create a new log file for every second, change it into “yyyyMMdd” if you want to create a daily appender.

log4j.rootLogger=DEBUG, request

log4j.appender.request=org.apache.log4j.rolling.RollingFileAppender
log4j.appender.request.File=msg.log
log4j.appender.request.RollingPolicy=org.apache.log4j.rolling.TimeBasedRollingPolicy
log4j.appender.request.RollingPolicy.ActiveFileName =msg.log
log4j.appender.request.RollingPolicy.FileNamePattern=msg.%d{yyyyMMdd.HHmmss}.gz
log4j.appender.request.layout = org.apache.log4j.PatternLayout
log4j.appender.request.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

And my simple java test case

package com.edw.compresslogfile;

import org.apache.log4j.Logger;

/**
 * Hello world!
 *
 */
public class App {

    private static final Logger LOGGER = Logger.getLogger(App.class);

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            try {
                LOGGER.debug("Hello World " + i);
                Thread.sleep(5000);
            } catch (Exception e) {
            }
        }
    }
}

It will create a compressed log file for every second.

This is the project structure on my Netbeans,

Hope it helped others, cheers (B)

Simulate A Post Request Using Java

Today, i’ll do a simple example on how to simulate a http post request using Apache Common Http Components. This is a usefull utility, because i use it heavily on many projects, specially to do a simple messaging between desktop clients and the server side. Very simple, very lightweight and also very reliable.

Okay, first i start with the server version of the application. I create a new WebProject on Netbeans, create a simple servlet and deploy it on tomcat. This is a very simple servlet to print on netbeans console and give response whether 0 if failed, or 1 if succeed.

package com.edw.servlet;

import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;

public class LoginServlet extends HttpServlet {
    
    private Logger logger = Logger.getLogger(LoginServlet.class);
    
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        try {
            String username = request.getParameter("username");
            String password = request.getParameter("password");
            
            logger.debug("receiving post " + username + " and " + password);
            response.getWriter().write("1");
        } catch (Exception e) {
            logger.error(e,e);
            response.getWriter().write("0");
        }                
    }
}

As usual, i register my servlet on web.xml.

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
    <servlet>
        <servlet-name>loginServlet</servlet-name>
        <servlet-class>com.edw.servlet.LoginServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>loginServlet</servlet-name>
        <url-pattern>/loginServlet</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

And now is my client’s side Java application.

package com.edw.postsimulator;

import java.util.ArrayList;
import java.util.List;
import org.apache.http.Consts;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

public class PostSimulator {
    
    // this is your target url
    private static String url = "http://localhost:8084/WebTestPost/loginServlet";
    
    public static void main(String[] args) throws Exception  {
        HttpClient httpclient = new DefaultHttpClient();
        HttpPost httpPost = new HttpPost(url);

        // set the parameters
        List <NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("username", "edwin"));
        nvps.add(new BasicNameValuePair("password", "dodol"));

        // set the encoding
        httpPost.setEntity(new UrlEncodedFormEntity(nvps, Consts.UTF_8));

        // send the http request and get the http response
        HttpResponse response = httpclient.execute(httpPost);
        HttpEntity resEntity = response.getEntity();
		
        // read the server's response contents
        System.out.println(EntityUtils.toString(resEntity));
    }
}

These are what is written on my Netbean’s console,

And this is my Netbean’s project configurations

Hope it helped others, Cheers :-[