From 52466067d8d3b94f40540f6ad01220847454cdc4 Mon Sep 17 00:00:00 2001 From: theli Date: Thu, 19 Oct 2006 08:33:53 +0000 Subject: [PATCH] *) Bugfix for ArrayIndexOutOfBoundsExceptions which occure because SimpleDateFormat is not thread-safe See: http://www.yacy-forum.de/viewtopic.php?t=2995 git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@2810 6c8d7289-2bf4-0310-a012-ef5d649a1542 --- htroot/yacy/hello.java | 2 +- source/de/anomic/yacy/yacyCore.java | 29 +++++++++++++++++++--- source/de/anomic/yacy/yacyPeerActions.java | 4 +-- source/de/anomic/yacy/yacySeed.java | 8 +++--- 4 files changed, 33 insertions(+), 10 deletions(-) diff --git a/htroot/yacy/hello.java b/htroot/yacy/hello.java index b710ffe3a..dc1c4f1df 100644 --- a/htroot/yacy/hello.java +++ b/htroot/yacy/hello.java @@ -157,7 +157,7 @@ public final class hello { yacyCore.peerActions.peerArrival(remoteSeed, true); } else { prop.put(yacySeed.YOURTYPE, yacySeed.PEERTYPE_JUNIOR); - remoteSeed.put(yacySeed.LASTSEEN, yacyCore.shortFormatter.format(new Date(System.currentTimeMillis() + serverDate.UTCDiff() - remoteSeed.getUTCDiff())) ); + remoteSeed.put(yacySeed.LASTSEEN, yacyCore.universalDateShortString(new Date(System.currentTimeMillis() + serverDate.UTCDiff() - remoteSeed.getUTCDiff())) ); yacyCore.peerActions.juniorConnects++; // update statistics remoteSeed.put(yacySeed.PEERTYPE, yacySeed.PEERTYPE_JUNIOR); yacyCore.log.logInfo("hello: responded remote junior peer '" + remoteSeed.getName() + "' from " + reportedip); diff --git a/source/de/anomic/yacy/yacyCore.java b/source/de/anomic/yacy/yacyCore.java index 576882eb4..b56a8edaa 100644 --- a/source/de/anomic/yacy/yacyCore.java +++ b/source/de/anomic/yacy/yacyCore.java @@ -62,6 +62,7 @@ import java.io.FilenameFilter; import java.io.IOException; import java.net.MalformedURLException; import java.net.URI; +import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Collections; import java.util.Date; @@ -121,7 +122,7 @@ public class yacyCore { private static TimeZone GMTTimeZone = TimeZone.getTimeZone("America/Los_Angeles"); public static String universalDateShortPattern = "yyyyMMddHHmmss"; - public static SimpleDateFormat shortFormatter = new SimpleDateFormat(universalDateShortPattern); + private static SimpleDateFormat shortFormatter = new SimpleDateFormat(universalDateShortPattern); public static long universalTime() { return universalDate().getTime(); @@ -136,14 +137,36 @@ public class yacyCore { } public static String universalDateShortString(Date date) { - return shortFormatter.format(date); + /* + * This synchronized is needed because SimpleDateFormat is not thread-safe. + * See: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6231579 + */ + synchronized(yacyCore.shortFormatter) { + return shortFormatter.format(date); + } + } + + public static Date parseUniversalDate(String timeString) throws ParseException { + /* + * This synchronized is needed because SimpleDateFormat is not thread-safe. + * See: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6231579 + */ + synchronized(yacyCore.shortFormatter) { + return yacyCore.shortFormatter.parse(timeString); + } } public static Date parseUniversalDate(String remoteTimeString, String remoteUTCOffset) { if (remoteTimeString == null || remoteTimeString.length() == 0) { return new Date(); } if (remoteUTCOffset == null || remoteUTCOffset.length() == 0) { return new Date(); } try { - return new Date(yacyCore.shortFormatter.parse(remoteTimeString).getTime() - serverDate.UTCDiff() + serverDate.UTCDiff(remoteUTCOffset)); + /* + * This synchronized is needed because SimpleDateFormat is not thread-safe. + * See: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6231579 + */ + synchronized(yacyCore.shortFormatter) { + return new Date(yacyCore.shortFormatter.parse(remoteTimeString).getTime() - serverDate.UTCDiff() + serverDate.UTCDiff(remoteUTCOffset)); + } } catch (java.text.ParseException e) { log.logFinest("parseUniversalDate " + e.getMessage() + ", remoteTimeString=[" + remoteTimeString + "]"); return new Date(); diff --git a/source/de/anomic/yacy/yacyPeerActions.java b/source/de/anomic/yacy/yacyPeerActions.java index 6c926fd89..f09107cad 100644 --- a/source/de/anomic/yacy/yacyPeerActions.java +++ b/source/de/anomic/yacy/yacyPeerActions.java @@ -325,7 +325,7 @@ public class yacyPeerActions { dtimeUTC0 = 0; // never disconnected: virtually disconnected maximum time ago } else { try { - dtimeUTC0 = yacyCore.shortFormatter.parse(disconnectedSeed.get("disconnected", "20040101000000")).getTime() - seed.getUTCDiff(); + dtimeUTC0 = yacyCore.parseUniversalDate(disconnectedSeed.get("disconnected", "20040101000000")).getTime() - seed.getUTCDiff(); } catch (java.text.ParseException e) { dtimeUTC0 = 0; } @@ -371,7 +371,7 @@ public class yacyPeerActions { try { // if the old LastSeen date is later then the other // info, then we reject the info - if ((ctimeUTC0 < (yacyCore.shortFormatter.parse(connectedSeed.get(yacySeed.LASTSEEN, "20040101000000")).getTime() - connectedSeed.getUTCDiff() + serverDate.UTCDiff())) && (!(direct))) { + if ((ctimeUTC0 < (yacyCore.parseUniversalDate(connectedSeed.get(yacySeed.LASTSEEN, "20040101000000")).getTime() - connectedSeed.getUTCDiff() + serverDate.UTCDiff())) && (!(direct))) { yacyCore.log.logFine("connect: rejecting old info about peer '" + seed.getName() + "'"); return false; } diff --git a/source/de/anomic/yacy/yacySeed.java b/source/de/anomic/yacy/yacySeed.java index 4447c9d12..0c6dd4608 100644 --- a/source/de/anomic/yacy/yacySeed.java +++ b/source/de/anomic/yacy/yacySeed.java @@ -270,7 +270,7 @@ public class yacySeed { public final void setJunior() { put(yacySeed.PEERTYPE, yacySeed.PEERTYPE_JUNIOR); } public final void setSenior() { put(yacySeed.PEERTYPE, yacySeed.PEERTYPE_SENIOR); } public final void setPrincipal() { put(yacySeed.PEERTYPE, yacySeed.PEERTYPE_PRINCIPAL); } - public final void setLastSeen() { put(yacySeed.LASTSEEN, yacyCore.shortFormatter.format(new Date(System.currentTimeMillis() + serverDate.UTCDiff() - getUTCDiff()))); } + public final void setLastSeen() { put(yacySeed.LASTSEEN, yacyCore.universalDateShortString(new Date(System.currentTimeMillis() + serverDate.UTCDiff() - getUTCDiff()))); } public final void put(String key, String value) { synchronized (this.dna) { @@ -367,7 +367,7 @@ public class yacySeed { public final long getLastSeenTime() { try { - final long t = yacyCore.shortFormatter.parse(get(yacySeed.LASTSEEN, "20040101000000")).getTime(); + final long t = yacyCore.parseUniversalDate(get(yacySeed.LASTSEEN, "20040101000000")).getTime(); // the problem here is: getTime applies a time shift according to local time zone: // it substracts the local UTF offset, but it should subtract the remote UTC offset // so we correct it by first adding the local UTF offset and then subtracting the remote @@ -384,7 +384,7 @@ public class yacySeed { public final int getAge() { // returns the age as number of days try { - final long t = yacyCore.shortFormatter.parse(get(yacySeed.BDATE, "20040101000000")).getTime(); + final long t = yacyCore.parseUniversalDate(get(yacySeed.BDATE, "20040101000000")).getTime(); return (int) ((System.currentTimeMillis() - (t - getUTCDiff() + serverDate.UTCDiff())) / 1000 / 60 / 60 / 24); } catch (java.text.ParseException e) { return -1; @@ -395,7 +395,7 @@ public class yacySeed { public final void setLastSeenTime() { // if we set a last seen time, then we need to respect the seeds UTC offset - put(yacySeed.LASTSEEN, yacyCore.shortFormatter.format(new Date(System.currentTimeMillis() - serverDate.UTCDiff() + getUTCDiff()))); + put(yacySeed.LASTSEEN, yacyCore.universalDateShortString(new Date(System.currentTimeMillis() - serverDate.UTCDiff() + getUTCDiff()))); } public void setPeerTags(Set keys) {