Explicitly Setting log4j Configuration File Location

I ran into an issue recent­ly, where an exist­ing log4j.xml con­fig­u­ra­tion file was built into a jar file I was ref­er­enc­ing and I was unable to get Java to rec­og­nize anoth­er file that I want­ed it to use instead.  For­tu­nate­ly, the solu­tion to this prob­lem is fair­ly straight­for­ward and sim­ple.

I was run­ning a stand­alone appli­ca­tion in lin­ux, via a bash shell script; but this tech­nique can be used in oth­er ways too.  You sim­ply add a para­me­ter to the JVM call like the exam­ple below.

So the syn­tax is basi­cal­ly:

java -Dlog4j.configuration="file:<full path to file>" -cp <classpath settings> <package name where my main function is located>

Lets say I have a file named log4j.xml in /opt/tools/myapp/ which I want to use when my appli­ca­tion runs, instead of any exist­ing log4j.xml files.  This can be done by pass­ing a JVM flag –Dlog4j.configuration to Java.

Here is an exam­ple:

java -Dlog4j.configuration="file:/opt/tools/myapp/log4j.xml" -cp $CLASSPATH  my.standalone.mainClass;

With that change, as long as your log4j file is set up prop­er­ly, your prob­lems should be behind you.

Fixing Performance Problems on Your JBoss Web Apps By Diagnosing Blocked Thread Issues

I was once per­plexed by a bizarre per­for­mance issue, I encoun­tered at seem­ing­ly ran­dom inter­vals, in an appli­ca­tion I help to main­tain. The appli­ca­tion kept freez­ing up, with­out any log mes­sages to use for diag­no­sis. This was very frus­trat­ing, because it meant the appli­ca­tion server typ­i­cal­ly had to be restart­ed man­u­al­ly to restore ser­vice.

After a bit of research, I learned of thread block­ing, as a poten­tial per­for­mance issue. Being as I was fair­ly cer­tain that the data­base was func­tion­ing with­in accept­able para­me­ters and the server had ample CPU and mem­o­ry to han­dle the load. I sought to deter­mine if thread block­ing was an issue.

I start­ed by sim­ply run­ning a twid­dle com­mand to dump the threads, when­ev­er this per­for­mance prob­lem was report­ed. This showed that the BLOCKED threads were indeed the cause. Con­tin­ue read­ing “Fix­ing Per­for­mance Prob­lems on Your JBoss Web Apps By Diag­nos­ing Blocked Thread Issues”

Streaming Data as Downloadable Files in Struts Servlet

One way to stream data to the client, is to use the Print­Writer, a library which allows you to direct­ly manip­u­late the out­put stream which is sent to the client. One of the ben­e­fits of stream­ing the out­put to the client with Print­Writer, is the abil­i­ty to send data as it is gen­er­at­ed; instead of hav­ing to buffer all of the data on the server, then send the data to the client after the entire set is gen­er­at­ed.

For con­ve­nience and espe­cial­ly for large files, it is impor­tant to mod­i­fy the HTTP head­ers in HttpServle­tRe­spon­se, instruct­ing the client’s browser to save the file to disk.

The fol­low­ing is a min­i­mal  exam­ple, which shows how to dump a dum­my CSV text file as a down­load­able file in a struts Action Servlet.

public class CsvDataDumpAction extends Action {
 
	public ActionForward execute
	(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
	{
		// declare the PrintWriter object for later instantiation
		PrintWriter pw = null;
 
		// modify the HTTP response header, so the file is downloaded as DataDump.txt
		response.setHeader("Content-disposition", "attachment; filename=DataDump.txt");
		response.setContentType("application/octet-stream");
 
		// catch the IOException generated by the PrintWriter
		try {
			// Sample header with four fields
			String header = "Field1,Field2,Field3,Field4";
			pw.println(header);
			// flush the buffer, sending the header line to the client
			pw.flush();
 
			// generate 1000 lines of dummy test data, with the field name, followed by the number of the row
			for(int i = 0; i &lt; 1000; i++) {
				pw.println("Field1_"+i+",Field2_"+i+",Field3_"+i+",Field4_"+i);
				// flush the buffer after each line is generated,
				// sending the data to the client as it is generated
				pw.flush();
			} 
 
			// show stack traces for the PrintWriter in the logs
		} catch (IOException e) { 	e.printStackTrace(); 	}
		return null;
	}
}