Beranda · · · ·

New Problem accessing Gmail using Nokia 6320i or any S40 v2,v3 phone By Patricbensen

...well, not any more!

Nokia's S40 v2 and v3 phones dont have a way to specify a proxy for an 'Access Point' configuration that you make. This means that your gmail midlet, email and other programs cant use the access point that you create for your GPRS connection.

The trick is to send to 'send' (just like your ISP does) your phone a wbxml provisioning script to allow JAVA apps to use a proxy for Series 40 v2 and v3 phones. All credit to the kool kat Mr RaviDavi from Austin, TX, USA for creating and sharing with these configurations with us. The configurations can be found here.

You'll need to get your required configuration onto your phone now. Bluetooth Object Push doesn't work on some phones.

If it doesn't, just head over to nowsms and download their sms gateway.


  • Install it,
  • connect your phone to your PC/Laptop where the software is installed. You can use a USB data cable or bluetooth
  • set up your phone as a modem on the PC/laptop,
  • start the nowsms gateway,
  • select your phone modem as the smsc gateway, click Test, you're almost there if it works,
  • start the smsc and mmsc services,
  • open the nowsms web application,
  • click on Send XML
  • paste the correct .wml file (from the above zip file) contents into the big text box,
  • Type a OTA pin, eg 1234
  • Dont select Network Pin - select the other one,
  • type your mobile phone number into the address box,
  • hit submit.

You should now receive the settings on your mobile phone.
Activate that configuration and your worries are over.

New ZoneAlarm Free Version - Full Download Link By Patricbensen

For all those of you behind a firewall, here is the link to download the full version of the ZoneAlarm Free edition.

Just click on the link below:
ZoneAlarm Free (1025)

http://redirect.zonelabs.com/redirect/route?mode=1&app=inclient&date=1&dest=stub&oem=1025&prod=0&lang=en&link_id=1

Cheers!

New Java - calculate the difference between two dates By Patricbensen

Finding the difference between two dates isn't as straightforward as subtracting the two dates and dividing the result by (24 * 60 * 60 * 1000). Infact, its erroneous! 

Going the 'milliseconds way' will lead to rounding off errors and they become most evident once you have a little thing like "Daylight Savings Time" come into the picture.

The Correct Way:

/** Using Calendar - THE CORRECT WAY**/
//assert: startDate must be before endDate
public static long daysBetween(Calendar startDate, Calendar endDate) {
Calendar date = (Calendar) startDate.clone();
long daysBetween = 0;
while (date.before(endDate)) {
date.add(Calendar.DAY_OF_MONTH, 1);
daysBetween++;
}
return daysBetween;
}
}

or more efficiently, (thanks Mauro), if you're using the Gregorian Calendar:
/** Using Calendar - THE CORRECT (& Faster) WAY**/
/****Needs testing ...... Anyone?****/
//assert: startDate must be before endDate
public static long daysBetween(final Calendar startDate, final Calendar endDate) {
int MILLIS_IN_DAY = 1000 * 60 * 60 * 24;
long endInstant = endDate.getTimeInMillis();
int presumedDays = (int) ((endInstant - startDate.getTimeInMillis()) / MILLIS_IN_DAY);
Calendar cursor = (Calendar) startDate.clone();
cursor.add(Calendar.DAY_OF_YEAR, presumedDays);
long instant = cursor.getTimeInMillis();
if (instant == endInstant)
return presumedDays;
final int step = instant < endInstant ? 1 : -1;
do {
cursor.add(Calendar.DAY_OF_MONTH, step);
presumedDays += step;
} while (cursor.getTimeInMillis() != endInstant);
return presumedDays;
}



The Nuances:

Lets take, for example, the difference between the two dates
03/24/2007 and 03/25/2007 should be 1 day; 

However, using the millisecond route, you'll get 0 days, if you run this in the UK!


import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

public class DateTest {

public class DateTest {

static SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy");

public static void main(String[] args) {

TimeZone.setDefault(TimeZone.getTimeZone("Europe/London"));

//diff between these 2 dates should be 1
Date d1 = new Date("01/01/2007 12:00:00");
Date d2 = new Date("01/02/2007 12:00:00");

//diff between these 2 dates should be 1
Date d3 = new Date("03/24/2007 12:00:00");
Date d4 = new Date("03/25/2007 12:00:00");

Calendar cal1 = Calendar.getInstance();cal1.setTime(d1);
Calendar cal2 = Calendar.getInstance();cal2.setTime(d2);
Calendar cal3 = Calendar.getInstance();cal3.setTime(d3);
Calendar cal4 = Calendar.getInstance();cal4.setTime(d4);

printOutput("Manual ", d1, d2, calculateDays(d1, d2));
printOutput("Calendar ", d1, d2, daysBetween(cal1, cal2));
System.out.println("---");
printOutput("Manual ", d3, d4, calculateDays(d3, d4));
printOutput("Calendar ", d3, d4, daysBetween(cal3, cal4));
}


private static void printOutput(String type, Date d1, Date d2, long result) {
System.out.println(type+ "- Days between: " + sdf.format(d1)
+ " and " + sdf.format(d2) + " is: " + result);
}

/** Manual Method - YIELDS INCORRECT RESULTS - DO NOT USE**/
/* This method is used to find the no of days between the given dates */
public static long calculateDays(Date dateEarly, Date dateLater) {
return (dateLater.getTime() - dateEarly.getTime()) / (24 * 60 * 60 * 1000);
}

/** Using Calendar - THE CORRECT WAY**/
public static long daysBetween(Calendar startDate, Calendar endDate) {
Calendar date = (Calendar) startDate.clone();
long daysBetween = 0;
while (date.before(endDate)) {
date.add(Calendar.DAY_OF_MONTH, 1);
daysBetween++;
}
return daysBetween;
}
}

OUTPUT:
Manual - Days between: 01-Jan-2007 and 02-Jan-2007 is: 1
Calendar - Days between: 01-Jan-2007 and 02-Jan-2007 is: 1
---
Manual - Days between: 24-Mar-2007 and 25-Mar-2007 is: 0
Calendar - Days between: 24-Mar-2007 and 25-Mar-2007 is: 1

New Java's UTF-8 and Unicode writing is broken - Use this fix By Patricbensen

Many of you might not believe this but try creating a file in UTF-8 encoding using a java program like this one (found on the java tutorial site)
//example from Sun - Incorrect output
static void writeOutput(String str) {

try {
FileOutputStream fos = new FileOutputStream("test.txt");
Writer out = new OutputStreamWriter(fos, "UTF8");
out.write(str);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}


This will create a file alright, but that file will not be a true UTF-8 file. Infact, this is a known and documented bug in the JDK that SUN will never fix!
There are other problems with the java.io package when it comes to unicode, for example, the OutputStreamWriter will not write an ASCII stream correctly leaving a '?' at the beginning of the output stream if input stream was Unicode.

After scouring the internet for information on how to get around this, I decided to write a general purpose Unicode converter that would convert FROM and TO any of the following formats:
UTF-8, UTF-16LE, UTF-16BE, UTF-32LE, UTF-32BE, ASCII

Usage:
byte[] outbytes = UnicodeUtils.convert(byte[] inbytes, String desiredoutputEncoding);
(The convertor will auto-sense the encoding of the input bytes)

The famous Shanghai Example:



//Example of usage:
String shanghai = "\u4E0A\u6D77";
byte[] out = UnicodeUtil.convert(shanghai.getBytes("UTF-16"), "UTF-8"); //Shanghai in Chinese
FileOutputStream fos = new FileOutputStream("/tmp/out.htm);
fos.write(out);
fos.close();


The following is the code for UnicodeUtils.java




import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PushbackInputStream;
import java.io.UnsupportedEncodingException;
import java.io.Writer;

public class UnicodeUtil {

public static byte[] convert(byte[] bytes, String encout) throws Exception {
// Workaround for bug that will not be fixed by SUN
// http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4508058
UnicodeInputStream uis = new UnicodeInputStream(new ByteArrayInputStream(bytes), "ASCII");
boolean unicodeOutputReqd = (getBOM(encout) != null) ? true : false;
String enc = uis.getEncoding();
String BOM = getBOM(enc); // get the BOM of the inputstream

if (BOM == null) {
// inputstream looks like ascii...
// create a BOM based on the outputstream
BOM = getBOM(encout);
}
uis.close();

ByteArrayOutputStream out = new ByteArrayOutputStream();
BufferedReader br = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bytes, uis.getBOMOffset(), bytes.length), enc));
Writer w = new BufferedWriter(new OutputStreamWriter(out, encout));

// dont write a BOM for ascii(out) as the OutputStreamWriter
// will not process it correctly.
if (BOM != null && unicodeOutputReqd) {
w.write(BOM);
}

char[] buffer = new char[4096];
int len;
while ((len = br.read(buffer)) != -1) {
w.write(buffer, 0, len);
}

br.close(); // Close the input.
w.close(); // Flush and close output.
return out.toByteArray();
}

public static String getBOM(String enc) throws UnsupportedEncodingException {
if ("UTF-8".equals(enc)) {
byte[] bom = new byte[3];
bom[0] = (byte) 0xEF;
bom[1] = (byte) 0xBB;
bom[2] = (byte) 0xBF;
return new String(bom, enc);
} else if ("UTF-16BE".equals(enc)) {
byte[] bom = new byte[2];
bom[0] = (byte) 0xFE;
bom[1] = (byte) 0xFF;
return new String(bom, enc);
} else if ("UTF-16LE".equals(enc)) {
byte[] bom = new byte[2];
bom[0] = (byte) 0xFF;
bom[1] = (byte) 0xFE;
return new String(bom, enc);
} else if ("UTF-32BE".equals(enc)) {
byte[] bom = new byte[4];
bom[0] = (byte) 0x00;
bom[1] = (byte) 0x00;
bom[2] = (byte) 0xFE;
bom[3] = (byte) 0xFF;
return new String(bom, enc);
} else if ("UTF-32LE".equals(enc)) {
byte[] bom = new byte[4];
bom[0] = (byte) 0x00;
bom[1] = (byte) 0x00;
bom[2] = (byte) 0xFF;
bom[3] = (byte) 0xFE;
return new String(bom, enc);
} else {
return null;
}

}

public static class UnicodeInputStream extends InputStream {
private PushbackInputStream internalIn;

private boolean isInited = false;

private int BOMOffset = -1;

private String defaultEnc;

private String encoding;

public static final int BOM_SIZE = 4;

public UnicodeInputStream(InputStream in, String defaultEnc) {
internalIn = new PushbackInputStream(in, BOM_SIZE);
this.defaultEnc = defaultEnc;
}

public String getDefaultEncoding() {
return defaultEnc;
}

public String getEncoding() {
if (!isInited) {
try {
init();
} catch (IOException ex) {
IllegalStateException ise = new IllegalStateException("Init method failed.");
ise.initCause(ise);
throw ise;
}
}
return encoding;
}

/**
* Read-ahead four bytes and check for BOM marks. Extra bytes are unread
* back to the stream, only BOM bytes are skipped.
*/
protected void init() throws IOException {
if (isInited)
return;

byte bom[] = new byte[BOM_SIZE];
int n, unread;
n = internalIn.read(bom, 0, bom.length);

if ((bom[0] == (byte) 0x00) && (bom[1] == (byte) 0x00) && (bom[2] == (byte) 0xFE) && (bom[3] == (byte) 0xFF)) {
encoding = "UTF-32BE";
unread = n - 4;
} else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE) && (bom[2] == (byte) 0x00) && (bom[3] == (byte) 0x00)) {
encoding = "UTF-32LE";
unread = n - 4;
} else if ((bom[0] == (byte) 0xEF) && (bom[1] == (byte) 0xBB) && (bom[2] == (byte) 0xBF)) {
encoding = "UTF-8";
unread = n - 3;
} else if ((bom[0] == (byte) 0xFE) && (bom[1] == (byte) 0xFF)) {
encoding = "UTF-16BE";
unread = n - 2;
} else if ((bom[0] == (byte) 0xFF) && (bom[1] == (byte) 0xFE)) {
encoding = "UTF-16LE";
unread = n - 2;
} else {
// Unicode BOM mark not found, unread all bytes
encoding = defaultEnc;
unread = n;
}
BOMOffset = BOM_SIZE - unread;
if (unread > 0)
internalIn.unread(bom, (n - unread), unread);

isInited = true;
}

public void close() throws IOException {
// init();
isInited = true;
internalIn.close();
}

public int read() throws IOException {
// init();
isInited = true;
return internalIn.read();
}

public int getBOMOffset() {
return BOMOffset;
}
}

}



New Freeware (older) version of DJ Java Decompiler By Patricbensen


DJ Java Decompiler is a great piece of software that allows you to decompile java class files into java source. It internally uses JAD as the decompiling engine.

The latest and greatest versions of DJ found on here. There are however some caveats with the newer versions (See below for the link to the old version)
  1. Not freeware anymore - License: Free to try; $19.99 to buy.
  2. Creepy stats and personal information collection feature that you must agree to!


Well, this doesn't sound very nice to me. After all JAD is free.

Did a bit of
googling, searching for a site that hopefully hosts the older and free version - Java Decompiler 3.7.7.81 and got the feeling that DJ had stripped the web of the free version.

After punching the magic keyword "old version" in google I found the free version (which they promptly replaced with the new one).
(Update: they've replaced the free version on that page to a paid trial version. Thanks to Atanas for the following direct link to the free version : http://dj.navexpress.com/djdec377.zip)

Thought I'd share it with y'all lazy people ;)

Enjoy!

Update: DJ doesn't do Java 5/6 class decompilation very well. The best one on the block currently is JD (http://java.decompiler.free.fr/). Check it out. It has eclipse integration too.

New Clear Putty's Cache By Patricbensen

For all those of you who have been trying to clear Putty’s cache of host fingerprints (Windows) for development or testing, here is the answer:

1. Open the registry (regedit)
2. Go to HKEY_CURRENT_USER\Software\SimonTatham\PuTTY\SshHostKeys

There you should see Putty’s cache of host keys.
The ‘name’ column tells you which key is for which server.

For example, it will have the format of <algo>@<port>:<host> [rsa2@22:172.16.117.159]

3. Delete the rows that you need and presto!

That’s all there is to it.

New Print JNDI tree By Patricbensen

At one point or another most of us would have wanted to see what was in the JNDI tree of the Application Server. This may have been because of a javax.naming.NameNotFoundException thrown by the application under development.

After scouring the internet and not finding a way to do this seemingly simple task, I put this together in about an hours time.

import java.util.Hashtable;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NameClassPair;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;

public class JNDITree {
private Context context = null;

public static void main(String[] args) throws Exception {
new JNDITree().printJNDITree("");
System.out.println("DONE");
}

public JNDITree() throws NamingException {
setEnv();
}

/* Please modify this method or comment and use jndi.properties
*/
public void setEnv() throws NamingException {
Hashtable env = new Hashtable();
//OC4J
// env.put(Context.INITIAL_CONTEXT_FACTORY, "com.evermind.server.rmi.RMIInitialContextFactory");
// env.put(Context.PROVIDER_URL, "ormi://172.16.x.x:12404");
// env.put(Context.SECURITY_PRINCIPAL, "admin");
// env.put(Context.SECURITY_CREDENTIALS, "welcome");
//JBOSS
// env.put(Context.INITIAL_CONTEXT_FACTORY, "org.jnp.interfaces.NamingContextFactory");
// env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming:org.jnp.interfaces");
// env.put(Context.PROVIDER_URL, "jnp://172.16.x.x:1099");
//WEBLOGIC
// env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
// env.put(Context.PROVIDER_URL, "t3://172.16.x.x:7001");


context = new InitialContext(env);
}

public void printJNDITree(String ct) {
try {
printNE(context.list(ct), ct);
} catch (NamingException e) {
//ignore leaf node exception
}
}

private void printNE(NamingEnumeration ne, String parentctx) throws NamingException {
while (ne.hasMoreElements()) {
NameClassPair next = (NameClassPair) ne.nextElement();
printEntry(next);
increaseIndent();
printJNDITree((parentctx.length() == 0) ? next.getName() : parentctx + "/" + next.getName());
decreaseIndent();
}
}

private void printEntry(NameClassPair next) {
System.out.println(printIndent() + "-->" + next);
}


private int indentLevel = 0;

private void increaseIndent() {
indentLevel += 4;
}

private void decreaseIndent() {
indentLevel -= 4;
}

private String printIndent() {
StringBuffer buf = new StringBuffer(indentLevel);
for (int i = 0; i < indentLevel; i++) {
buf.append(" ");
}
return buf.toString();
}



This seemed to have worked very well for me and I thought I'd share it incase any of you have the same need.
In case anyone has a better way of doing this, kindly comment.

P.S. Dont forget to edit the setEnv() method to set the InitialContext. Default values have been given for a few App Servers.
Alternatively, comment the method out and use jndi.properties with values corresponding to your application server.

New OC4JClient - The SCAM By Patricbensen

You'd think that when Oracle packages a jar called oc4jclient.jar, you'd be safe using it within your client (ejb client, jms client) applications with no problems whatsoever.... well, if you did, you'd be ...well...WRONG!
You might also encounter stacktraces like these after deploying your EJB/JMS client:

Exception in thread "main" java.lang.NoClassDefFoundError: com/evermind/server/jms/EvermindXAConnectionFactory
at com.evermind.server.jms.ConnectInfo.getPass(ConnectInfo.java:98)
at com.evermind.server.jms.EvermindQueueConnectionFactory.createQueueConnection(
EvermindQueueConnectionFactory.java:83)


There are a number of things to note before you even try to use the oc4jclient.jar:

  1. Oracle packages the client in a zip file. This file contains the oc4jclient.jar file and al lot of additional supporting libraries that it needs. Just check out the manifest.mf file present in oc4jclient.jar to marvel at the horrendous dependency list.

  2. In addition to the above, you will need to download an additional jar (ojdl.jar) required for the oc4jclient's internal logging purpose!. (How daft can this be!)

  3. You CANNOT distribute the OC4JClient (and its supporting libraries like dms.jar, optic.jar etc) unless you are an Oracle Customer and your client is an Oracle Customer. So be extremely careful while packaging and deploying your application.


  4. The OC4JClient (oc4jclient.jar along with supporting jars) is INADEQUATE if you want to build a client application that uses JMS (not OJMS). For this to work, you'll have to add oc4j.jar (i.e. the entire core runtime of the application server) just to make a standalone JMS client run (How clever is that?!)

The above definitely holds true for Oracle10gAS 10.1.2.02. I believe that with 10.1.3, some of these problems have been alleviated. However.....
The next time you develop an oc4j client application please keep the above points. This will avoid significant pain grief especially when trying to liaise with metalink/oracle tech support.

New Foxit : Adobe Acrobat Reader Replacement By Patricbensen

Fed up of Adobe Acrobat Reader's slow load times? Had enough of the huge download bills you keep paying thanks to its frequent and not so small updates?

Well, then Foxitsoftware.com is the place you want to go to... quickly.

There you'll find Foxit Reader 2.0.
  • Its incredibly small (~1.5MB).
  • Its lightning fast
  • It can annotate
  • Its FREE

The only thing I found it lacking in was the management of digital certificates and trusted identities. However, for the average user of pdf files, Foxit Reader should do very nicely.