February 19, 2008

HTML to Excel with JSP

response.setContentType("application/vnd.ms-excel");
response.setHeader("Content-Disposition","attachment; filename=" + "vmd.xls");
String htmlTable = (String)request.getParameter("htmlTable");
out.print(htmlTable); //htmlTable is string which contains HTML table code.

Basic JDBC: Executing a simple SELECT statement


// Load the JDBC driver.
Class.forName("COM.ibm.db2.jdbc.app.DB2Driver");

// Establish a connection
url = "jdbc:db2:INSURANCE";
username = "myName";
password="myPassword";
Connection connection = DriverManager.getConnection(url,username,password);

// Create and execute query
String query = "SELECT name, age, dob FROM COMMERCIAL.AUTO";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(query);
while (rs.next())
{
String name = rs.getString("name");
int age = rs.getInt("age");
Date = rs.getDate("dob");
}

connection.close();

Hibernate 3.0 config file with database URL


<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>

<!-- Properties -->
<property name="dialect">org.hibernate.dialect.DB2Dialect</property>
<property name="connection.driver_class">COM.ibm.db2.jdbc.app.DB2Driver</property>
<property name="connection.url">jdbc:db2:INSURANCE</property>
<property name="connection.username">myUsername</property>
<property name="connection.password">myPassword</property>
<property name="show_sql">true</property>
<property name="default_schema">COMMERCIAL</property>

<!-- Mapping files -->
<mapping resource="com/myCompany/myApp/mappings/Auto.hbm.xml"/>
<mapping resource="com/myCompany/myAppmappings/Building.hbm.xml"/>
<mapping resource="com/myCompany/myApp/mappings/AuditLog.hbm.xml"/>

</session-factory>
</hibernate-configuration>

Hibernate 3.0 config file with JNDI datasource


<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>

<!-- Properties -->
<property name="dialect">org.hibernate.dialect.DB2Dialect</property>
<property name="connection.datasource">jdbc/my jndi name</property>
<property name="show_sql">true</property>
<property name="default_schema">COMMERCIAL</property>

<!-- Mapping files -->
<mapping resource="com/myCompany/myApp/mappings/Auto.hbm.xml"/>
<mapping resource="com/myCompany/myApp/mappings/Building.hbm.xml"/>
<mapping resource="com/myCompany/myApp/mappings/AuditLog.hbm.xml"/>

</session-factory>
</hibernate-configuration>

Hibernate mapping file


<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
<class name="com.myCompany.myApp.beans.Refresh"
table="REFRESH"
lazy="true">

<id name="refreshId" type="integer" column="REFRESH_ID">
<generator class="assigned"/>
</id>

<timestamp name="timestamp" column="REFRESH_TIMESTAMP"/>
</class>
</hibernate-mapping>

org.hibernate.StaleObjectStateException

I got this error when I had two sessions open to two datasources. I was reading from one session and writing to the other session. This problem was solved when i used the replicate() method instead of the persist() method.


Another time, I was trying to read from an object after I had done an update() on it.

org.hibernate.StaleObjectStateException: Row was updated or deleted by another transaction
(or unsaved-value mapping was incorrect): [com.myCompany.myApp.beans.MyBean#5104]
at org.hibernate.persister.entity.BasicEntityPersister.check(BasicEntityPersister.java:1416)
at org.hibernate.persister.entity.BasicEntityPersister.update(BasicEntityPersister.java:1956)
at org.hibernate.persister.entity.BasicEntityPersister.updateOrInsert(BasicEntityPersister.java:1880)
at org.hibernate.persister.entity.BasicEntityPersister.update(BasicEntityPersister.java:2120)
at org.hibernate.action.EntityUpdateAction.execute(EntityUpdateAction.java:75)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:239)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:223)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:137)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:274)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:669)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:293)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:86)

Hibernate Tool - Reverse Engineering

Extract Hibernate tools and copy the contents of the plugins directory into the eclipse/plugins directory. Now re/start eclipse and right click on project. Select New->Other->Hibernate. You will see the following options:
1. Hibernate Configuration File (cfg.xml)
2. Console Configuration
3. Hibernate Artifact Generation

Run these wizards in the above sequence.

NOTE:
1. hibernate.jar file should not be included in 'Console Configuration'. The Hibernate Tool has its own hibernate.jar file.
2. Copy the database driver jar file into the project and make it available in your classpath. This is needed in 'Console Configuration'.
3. If your schema has a lot of tables, you may get an insufficient memory exception:

Error under artifact generation
Reason:
java.lang.OutOfMemoryError:Java heap space

In that case you try allocating more memory to Eclipse/WSAD:
C:\Jboss-Eclipse\eclipse\eclipse.exe -vmargs -Xms750M -Xmx750M

Please refer to the Hibernate tools documentation for further details.

Generic toString() using reflection

We can use this method to print the fields and their corresponding values in any object that implements it. This may be useful for debugging.

/**
* This method prints the details of this object
*/
public String toString() {
StringBuffer buffer = new StringBuffer( 512 );
buffer.append( "+++ " + this.getClass().getName() + "\n" );
java.lang.reflect.Field[] fields = this.getClass().getDeclaredFields();

for ( int i = 0; i < fields.length; i ) {
try {
buffer.append( " " + fields[i].getName() + ": " fields[i].get(this) + "\n" );
}
catch (Exception e) {
}
}
return buffer.toString();
}

SWT - Browser

// Show the browser
final Browser browser = new Browser(shell, SWT.NONE);
browser.setSize(500,500);
browser.setLocation(10,60);
browser.setUrl("http://www.stanleygeorge.com");

// Prepare a toolbar to show the 'forward' and 'back' navigation buttons
ToolBar navBar = new ToolBar(shell,SWT.HORIZONTAL);
navBar.setSize(150,50);
navBar.setLocation(10,10);

// The back button
final ToolItem back = new ToolItem(navBar, SWT.PUSH);
back.setText("back");
back.setEnabled(false);
// Add a listener so that it will go to the previous URL in history
back.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
browser.back();
}
});

// The code for the forward button is similar to the above code
// Use browser.forward(); instead of browser.back();

// Enable/disable the buttons automatically
LocationListener locationListener = new LocationListener() {
public void changed(LocationEvent event) {
Browser browser = (Browser)event.widget;
back.setEnabled(browser.isBackEnabled());
forward.setEnabled(browser.isForwardEnabled());
}
public void changing(LocationEvent event) {
}
};

browser.addLocationListener(locationListener);
Reference: http://www.eclipse.org/articles/Article-SWT-browser-widget/browser.html

SWT - Tree, Composite, Group, Tab, Popup Menu

Reference: http://www.cs.umanitoba.ca/~eclipse/
Tree
final Tree tree = new Tree(shell, SWT.MULTI | SWT.BORDER);
tree.setSize(150, 150);
tree.setLocation(5,5);

TreeItem myComp = new TreeItem(tree, SWT.NONE);
myComp.setText("My Computer");
TreeItem netPlaces = new TreeItem(tree, SWT.NONE);
netPlaces.setText("My Network Places");
TreeItem hardDisk = new TreeItem(myComp, SWT.NONE);
hardDisk.setText("Local Disk (C:)");


Composite
Composite composite = new Composite(shell,SWT.BORDER);
composite.setBounds(10,10,270,250);
composite.setBackground(new Color(display,31,133,31));

Label label = new Label(composite,SWT.NONE);
label.setText("Hello World");
label.setBounds(10,10,200,20);


Group
Group group = new Group(shell, SWT.BORDER);
group.setBounds(30,30,200,200);
group.setText("Group");

Button button = new Button(group, SWT.PUSH);
button.setBounds(10,20,80,20);
button.setText("In a group");


Tab
 TabFolder tabFolder = new TabFolder(shell,SWT.NONE);
tabFolder.setBounds(10,10,270,250);

Composite buttonComp = new Composite(tabFolder,SWT.NONE);
Button button1 = new Button(buttonComp,SWT.PUSH);
button1.setSize(100,100);
button1.setText("Hello");
button1.setLocation(0,0);
Button button2 = new Button(buttonComp,SWT.ARROW);
button2.setBounds(150,0,50,50);

TabItem item = new TabItem(tabFolder,SWT.NONE);
item.setText("Buttons");
item.setControl(buttonComp);

Fancy Tabs can be shown using CTabFolder and CTabItem. Reference: http://www.javalobby.org/java/forums/t16488.html
Popup Menu
Menu popupmenu = new Menu(shell, SWT.POP_UP);
MenuItem actionItem = new MenuItem(popupmenu, SWT.PUSH);
actionItem.setText("Other Action");
actionItem.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
System.out.println("Other Action performed!");
}
});

Menu popupmenu2 = new Menu(shell, SWT.POP_UP);
MenuItem buttonItem = new MenuItem(popupmenu2, SWT.PUSH);
buttonItem.setText("Button Action");
buttonItem.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
System.out.println("Button Action performed!");
}
});

Composite c1 = new Composite (shell, SWT.BORDER);
c1.setSize (100, 100);
c1.setLocation(25,25);
Button b = new Button(c1, SWT.PUSH);
b.setText("Button");
b.setSize(50,50);
b.setLocation(25,25);

SWT - Slider, Scale, Progress, Combo, Menu, ToolBar, CoolBar

Reference: http://www.cs.umanitoba.ca/~eclipse/
Slider
Slider slider1 = new Slider(shell, SWT.HORIZONTAL);
slider1.setBounds(0,0,200,20);
slider1.setSelection(50);
slider1.setMaximum(100);
slider1.setMinimum(0);
slider1.setThumb(30);


Scale
Scale scale1 = new Scale(shell, SWT.HORIZONTAL);
scale1.setBounds(0,40,200,40);
scale1.setMinimum(0);
scale1.setMaximum(500);
scale1.setSelection(100);
scale1.setPageIncrement(50);


Progress Bar
ProgressBar progressBar1 = new ProgressBar(shell,SWT.HORIZONTAL);
progressBar1.setMinimum(0);
progressBar1.setMaximum(100);
progressBar1.setSelection(30);
progressBar1.setBounds(0,100,250,20);


Combo
Combo combo1 = new Combo(shell, SWT.DROP_DOWN|SWT.READ_ONLY);
combo1.setItems(new String[] {"One","Two","Three"});
combo1.select(0);
combo1.setLocation(0,0);
combo1.setSize(100,20);

Combo combo2 = new Combo(shell, SWT.SIMPLE);
combo2.setItems(new String[] {"Four","Five","Six",});
combo2.setBounds(50,50,200,150);
combo2.select(1);


Menu
Menu menu = new Menu(shell, SWT.BAR);
shell.setMenuBar(menu);

MenuItem file = new MenuItem(menu, SWT.CASCADE);
file.setText("File");

Menu filemenu = new Menu(shell, SWT.DROP_DOWN);
file.setMenu(filemenu);

MenuItem actionItem = new MenuItem(filemenu, SWT.PUSH);
actionItem.setText("Action");

actionItem.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event e) {
System.out.println("Action performed!");
}
});


ToolBar
final ToolBar bar = new ToolBar(shell,SWT.HORIZONTAL);
bar.setSize(380,150);
bar.setLocation(10,10);

Image icon = new Image(display, "grayblock_v.gif"); // catch FileNotFoundException
ToolItem pushItem = new ToolItem(bar, SWT.PUSH);
pushItem.setText("Push");
pushItem.setImage(icon);


CoolBar
final CoolBar bar = new CoolBar(shell, SWT.BORDER);
CoolItem item1 = new CoolItem(bar, SWT.NONE);

Button button1 = new Button(bar, SWT.FLAT | SWT.BORDER);
button1.setText("Button");
button1.pack();

Point size = button1.getSize();
item1.setControl(button1);
item1.setSize(item1.computeSize(size.x, size.y));

bar.setWrapIndices(new int[] {3});
bar.setSize(300, 120);

SWT - Label, Text, Button, List, Table

Reference: http://www.cs.umanitoba.ca/~eclipse/

The Eclipse IDEs user interface in made with SWT (Standard Widget Toolkit). This is basic program in SWT:

import org.eclipse.swt.widgets.*;
import org.eclipse.swt.*;

public class HelloSWT {
public static void main(String[] args) {
Display display = new Display();
Shell shell = new Shell(display);

Label label = new Label(shell, SWT.NONE);
label.setText("Hello, World!");

shell.pack();
label.pack();

shell.open();
while(!shell.isDisposed())
if(!display.readAndDispatch())
display.sleep();
display.dispose();
label.dispose();
}
}


You can add various components in SWT in the following manner:
Label

Label label = new Label(shell, SWT.NONE);
label.setSize(100,20);
label.setLocation(30,150);
label.setBackground(new Color(display,200,111,50));
label.setText("Hello World");


Text

Text text = new Text(shell, SWT.BORDER);
text.setText("Hello World");
text.setBounds(10,10,200,20);
text.setTextLimit(30);


Button

Button button = new Button(shell,SWT.PUSH);
button.setText("Hello World");
button.setLocation(0,0);
button.setSize(100,20);
button.addSelectionListener(new SelectionAdapter() {
public void widgetSelected(SelectionEvent e) {
System.out.println("Button was clicked");
}
});


List

List list = new List(shell, SWT.MULTI | SWT.H_SCROLL);
list.setItems(new String[] {"Hello","World"});
list.add("SWT");
list.setBounds(0,0,60,100);

list.addMouseListener(new MouseAdapter() {
public void mouseDown(MouseEvent e) {
System.out.print(list.getSelection()[0]);
}

public void mouseUp(MouseEvent e) {
System.out.println(" selected");
}
});


Table

Table table = new Table(shell, SWT.FULL_SELECTION);
table.setLinesVisible(true);
table.setBounds(10,180,270,80);

TableColumn first = new TableColumn(table,SWT.LEFT);
first.setResizable(true);
first.setText("First");
first.setWidth(80);

TableColumn second = new TableColumn(table,SWT.CENTER);
second.setText("Second");
second.setWidth(80);

String[] numbers = new String[] {"One","Two"};

TableItem firstItem = new TableItem(table,SWT.NONE);
firstItem.setText(numbers);

Struts step-by-step

Reference: Jakarta Struts Live - Rick Hightower

Initialize
1 Create a project directory, say myProj
2 Copy struts-blank.war into myProj
3 Extract struts-blank.war into myProj
4 Copy log4j-1.2.9.jar into myProj (for logging; optional)
5 Modify myProj/WEB-INF/src/build.xml to point to the jar file that contains the Servlet API (for ant; optional). Eg. <property name="servlet.jar" value="F:/Program Files/Tomcat-5.0.28/common/lib/servlet-api.jar"/lt;
6 Create a package in myProj/WEB-INF/src/java, say myPack

Write Action
7 Write your Action in myPack, say MyAction.java, which extends Action and overrides the execute method:
package myPack;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
public class MyAction extends Action {
public ActionForward execute(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception {
return mapping.findForward("success");
}
}


Write Forward
8 Write you Forward in myProj, say myForward.jsp:
<html>
<head>
<title>My Action Was Successful!</title>
</head>
<body>
<h1> My Action Was Successful!</h1>
</body>
</html>


Configure Action and Forward
9 Add the following to myProj/WEB-INF/struts-config.xml:
<action path="/myAction" type="myPack.MyAction">
<forward name="success" path="/myForward.jsp"/>
</action>

NOTE
The above associates the incoming path /myAction with the Action handler you wrote earlier, myPack.MyAction. Whenever this web application gets a request with /myAction.do (already done in myProj/WEB-INF/web.xml), the execute method of the myPack.MyAction class will be invoked.
Configure Action and Forward in web.xml (already done in struts-blank.war). web.xml uses struts-config.xml as the struts configuration file.

Build
10 Modify build.xml to add the ${servlet.jar} file to the compile.classpath:
<pathelement path ="${servlet.jar}"/>
11 Modify build.xml to change the project.distname:
<property name="project.distname" value="myProj"/>
12 Modify build.xml to edit distpath.project:
<property name="distpath.project" value="F:/Program Files/Tomcat-5.0.28/webapps"/>
13 Run the ant script to get BUILD SUCCESSFUL:
C:\myProj\WEB-INF\src> ant
Deploy
14 Start Tomcat and point your browser to http://localhost:8080/myProj/myAction.do

Logging (optional, but recommended)
15 Add loj4j.properties to myProj\WEB-INF\src\java\:
log4j.rootLogger=WARN, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=[%5p] %d{mm:ss}(%F:%M:%L)%n%m%n%n
16 Edit MyAction.java:

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
...
private static Log log = LogFactory.getLog(MyAction.class);
public ActionForward execute(...) throws Exception {
log.trace("In execute method of MyAction");
return mapping.findForward("success");
...

17 Edit build.xml to add logging to compile.classpath:

18 Edit log4j.propertiles to add:
log4j.logger.myProj=DEBUG
NOTE: Levels of logging: FATAL, ERROR, WARN, INFO, DEBUG, TRACE

Write ActionForm
19 Create a class in myPack say MyForm that extends ActionForm and overrides reset, validate:
package myPack;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionError;
import javax.servlet.http.HttpServletRequest;
public class MyForm extends ActionForm {
private String firstName;
private Boolean registered;
public String getFirstName() {return firstName;}
public void setFirstName (String string) {firstName = string;}
public void reset(ActionMapping mapping,
HttpServletRequest request) {
firstName=null;
registered=false;
}
public ActionErrors validate(
ActionMapping mapping,
HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
if (firstName==null || firstName.trim().equals("")){
errors.add("firstName",
new ActionError(
"userRegistration.firstName.problem"));
}
return errors;
}
}

20 Edit myProj\WEB-INF\src\java\resources\application.properties and add:
myProj.firstName.problem=The first name was blank
21 Create my.jsp in myProj:

<%@ taglib uri="/tags/struts-html" prefix="html"%>
<%@ taglib uri="/tags/struts-bean" prefix="bean"%>
<html>
<head>
<title> My Project </title>
</head>
<body>
<h1>My Project</h1>
<html:errors/>
<table>
<html:form action="myProj">
<tr>
<td><bean:message key="myProj.firstName" />*</td>
<td><html:text property="firstName" /></td>
</tr>
<tr>
<td><html:submit /></td>
<td><html:cancel /></td>
</tr>
</html:form>
</table>
</body>
</html>

22 Modify struts.config.xml to add into form-beans:
<form-bean name="myForm" type="myPack.MyForm" />
23 Modify action so that it is:

<action path="/myProj" type="myPack.MyAction" name="myForm" input="/my.jsp">
<forward name="success" path="/regSuccess.jsp" />
</action>

24 Create labels for Form fields in application.properties (for internationalization) by adding:
myProj.firstName=First Name
25 Edit struts-config.xml to change:
<message-resources parameter="resources.application" />

JavaScript to select all checkboxes

function selectAll(obj) {
var checkboxCount = 0;
for(i=0;i<document.forms[0].elements.length;i++) {
if(document.forms[0].elements[i].name=="auditLogIds") {
checkboxCount++;
if(checkboxCount > 1) {
break;
}
}
}
if(checkboxCount > 1) {
for(i=0;i<document.forms[0].auditLogIds.length;i++) {
document.forms[0].auditLogIds[i].checked=obj.checked;
}
}
else {
document.forms[0].auditLogIds.checked=obj.checked;
}
return;
}

Fixed header in a datagrid

This piece of CSS will let you scroll the contents of you table while keeping the headers fixed.
<style type="text/css" media="screen">
#container{ border: solid 1px black;width: 50%; height:150px; overflow: auto; }
.noScroll { position:relative; top:expression(this.offsetParent.scrollTop);
background-color:white; font-family: Arial, Helvetica, sans-serif; }
</style>

<div id="container">
<table border="0" cellpadding="0" cellspacing="0" style="width: 100%">
<thead>
<tr class="noScroll">
<TH>...</TH>
</tr>
</thead>
<tbody>
<TR><TD>...</TD></TR>
</tbody>
</TABLE>
</div>

Reference:http://codebetter.com/blogs/geoff.appleby/archive/2004/10/23/29486.aspx

Log4J 1.3 RollingFileAppender

In version 1.3, RollingFileAppender reads configuration from an XML file. We need to read it using JoranConfigurator. This is an sample configuration called traceLogger.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration>

<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/' debug="true">

<appender name="ROLL" class="org.apache.log4j.rolling.RollingFileAppender">
<rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
<param name="FileNamePattern" value="/trace.%d{yyyy-MM-dd}.log"/>
</rollingPolicy>

<triggeringPolicy class="org.apache.log4j.rolling.SizeBasedTriggeringPolicy">
<param name="MaxFileSize" value="100000"/>
</triggeringPolicy>

<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%c{1} - %m%n"/>
</layout>
</appender>

<root>
<appender-ref ref="ROLL"/>
</root>

</log4j:configuration>

This is how we could configure it using JoranConfigurator:
new JoranConfigurator().doConfigure("traceLogger.xml", LogManager.getLoggerRepository());

HowTo - GCJ: A native Java Compiler

MinGW
MinGW[1] allows you to create native Windows programs. In other words, you can make an exe out of a Java program. The files required for the GCC Java complier are: gcc-java-3.4.2-20040916-1.tar.gz, mingw-runtime-3.9.tar.gz, w32api-3.6.tar.gz, binutils-2.15.91-20040904-1.tar.gz, gcc-core-3.4.2-20040916-1.tar.gz,

These files can be downloaded from the MinGW download page[2] . Additionally, linking requres the libiconv[3] library file libiconv-1.9.1.bin.woe32.zip. This file can be downloaded from its SourceForge.net page[4].

Unzip all the above files in a folder, say D:/mingw. The file gcj.exe will be in D:/mingw/bin. You can add this to the system PATH environment variable.

Compiling a program:
gcj -c -g -O Hello.java

Creating an exe file:
gcj --main=Hello -o Hello Hello.o

This will create a file called Hello.exe

Consider the following program Hello.java
class Hello {
public static void main(String args[]) {
System.out.println("Hello, World!");
}
}


This is a 117 bytes file that will normally require a 15MB JRE from Sun to execute. On the other hand, by using GCJ, the same program compiled into a 3.32MB Hello.exe file.

micro-libgcj
This size can be reduced if we use the minimal micro-libgcj[5] runtime. Note that this runtime supports only the bare minimim features in Java. So, most advanced features including Reflection are not supported.

References
1. http://www.mingw.org/
2. http://www.mingw.org/download.shtml
3. http://www.gnu.org/software/libiconv/
4. http://sourceforge.net/project/showfiles.php?group_id=25167&package_id=51458
5. http://ulibgcj.sourceforge.net/