> Hye,
>
> I think I have found a problem when stress testing my application with
> JDO/Castor 0.9.5.2.
> I have the stacktrace :
> java.lang.NumberFormatException: For input string: ""
> at
> java.lang.NumberFormatException.forInputString(NumberFormatException.java:
> 48)
> at java.lang.Long.parseLong(Long.java:415)
> at java.lang.Long.parseLong(Long.java:452)
> at java.text.DigitList.getLong(DigitList.java:149)
> at java.text.DecimalFormat.parse(DecimalFormat.java:1068)
> at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1705)
> at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1156)
> at java.text.DateFormat.parse(DateFormat.java:333)
> at
> org.exolab.castor.jdo.engine.SQLTypes$65.convert(SQLTypes.java:941)
> at
> org.exolab.castor.jdo.engine.SQLEngine.toJava(SQLEngine.java:490)
> at
> org.exolab.castor.jdo.engine.SQLEngine.access$500(SQLEngine.java:108)
> at
> org.exolab.castor.jdo.engine.SQLEngine$SQLQuery.loadSingleField(SQLEngine.
> java:1815)
> at
> org.exolab.castor.jdo.engine.SQLEngine$SQLQuery.loadRow(SQLEngine.java:188
> 1)
> at
> org.exolab.castor.jdo.engine.SQLEngine$SQLQuery.fetchRaw(SQLEngine.java:19
> 54)
> at
> org.exolab.castor.jdo.engine.SQLEngine$SQLQuery.nextIdentity(SQLEngine.jav
> a:1762)
> at
> org.exolab.castor.persist.QueryResults.nextIdentity(QueryResults.java:173)
> at
> org.exolab.castor.jdo.engine.OQLQueryImpl$OQLEnumeration.hasMore(OQLQueryI
> mpl.java:638)
> at
> org.exolab.castor.jdo.engine.OQLQueryImpl$OQLEnumeration.hasMore(OQLQueryI
> mpl.java:624)
>
>
> which seems to be relative to the problem of using SimpleDateFormat or a
> DateFormat in a multithread environnement
> whereas those classes are not thread-safe.
> Can somebody familiar with this part of Castor JDO, confirm this please ?
>
I can propose my patch. It works for me, but I'm not sure it's the good way
to answer the problem. <<patch-castor-sqltypes.txt>>
Ce message et toutes les pi�ces jointes (ci-apr�s le "message") sont �tablis �
l'intention exclusive de ses destinataires et sont confidentiels. Si vous recevez ce
message par erreur, merci de le d�truire et d'en avertir imm�diatement l'exp�diteur.
Toute utilisation de ce message non conforme � sa destination, modification, diffusion
ou toute publication, totale ou partielle, est interdite, sauf autorisation
expresse.FININFO (et ses filiales) d�cline(nt) toute responsabilit� au titre de ce
message, dans l'hypoth�se ou il aurait �t� modifi�, alt�r�, falsifi� ou encore �dit�
ou diffus� sans autorisation.
-----------------------------------------------------
This message and any attachments (the "message") is intended
solely for the addressees and is confidential. If you receive this
message in error, please delete it and immediately notify the
sender. Any use not in accord with its purpose, any dissemination
or disclosure, either whole or partial, is prohibited except formal
approval. Neither FININFO (nor any of its subsidiaries or affiliates)
shall be liable for the message if modified, altered, falsified, edited
or diffused without authorization.
--- castor-0.9.5.2-orig/src/main/org/exolab/castor/jdo/engine/SQLTypes.java
2003-09-29 05:11:08.000000000 +0200
+++ castor-0.9.5.2/src/main/org/exolab/castor/jdo/engine/SQLTypes.java 2003-11-12
10:50:15.000000000 +0100
@@ -543,7 +543,7 @@
* is specified.
*/
private static SimpleDateFormat _paramDateFormat = new SimpleDateFormat();
-
+
/**
* Date format used by the double->date convertor.
*/
@@ -649,8 +649,10 @@
} ),
new TypeConvertorInfo( new SQLTypeConvertor( java.util.Date.class,
java.lang.Integer.class ) {
public Object convert( Object obj, String param ) {
- _paramDateFormat.applyPattern(
org.exolab.castor.mapping.loader.Types.getFullDatePattern( param ) );
- return new Integer( _paramDateFormat.format( (java.util.Date) obj ) );
+ synchronized (_paramDateFormat){
+
_paramDateFormat.applyPattern(org.exolab.castor.mapping.loader.Types.getFullDatePattern(
param ));
+ return new Integer( _paramDateFormat.format(
(java.util.Date) obj ) );
+ }
}
} ),
// Convertors to long
@@ -754,8 +756,10 @@
} ),
new TypeConvertorInfo( new SQLTypeConvertor( java.util.Date.class,
java.lang.Double.class ) {
public Object convert( Object obj, String param ) {
- _paramDateFormat.applyPattern(
org.exolab.castor.mapping.loader.Types.getFullDatePattern( param ) );
- return new Double( _paramDateFormat.format( (java.util.Date) obj ) );
+ synchronized (_paramDateFormat){
+
_paramDateFormat.applyPattern(org.exolab.castor.mapping.loader.Types.getFullDatePattern(
param ));
+ return new Double( _paramDateFormat.format(
(java.util.Date) obj ) );
+ }
}
} ),
new TypeConvertorInfo( new SQLTypeConvertor( java.lang.String.class,
java.lang.Double.class ) {
@@ -829,8 +833,10 @@
} ),
new TypeConvertorInfo( new SQLTypeConvertor( java.util.Date.class,
java.math.BigDecimal.class ) {
public Object convert( Object obj, String param ) {
- _paramDateFormat.applyPattern(
org.exolab.castor.mapping.loader.Types.getFullDatePattern( param ) );
- return new BigDecimal( new BigInteger( _paramDateFormat.format(
(java.util.Date) obj ) ) );
+ synchronized (_paramDateFormat){
+
_paramDateFormat.applyPattern(org.exolab.castor.mapping.loader.Types.getFullDatePattern(
param ));
+ return new BigDecimal( new BigInteger(
_paramDateFormat.format( (java.util.Date) obj ) ) );
+ }
}
} ),
new TypeConvertorInfo( new SQLTypeConvertor( java.lang.Boolean.class,
java.math.BigDecimal.class ) {
@@ -874,8 +880,10 @@
if ( param == null || param.length() == 0 )
return obj.toString();
else {
- _paramDateFormat.applyPattern( param );
- return _paramDateFormat.format( (java.util.Date) obj );
+ synchronized (_paramDateFormat){
+ _paramDateFormat.applyPattern(param);
+ return _paramDateFormat.format(
(java.util.Date) obj );
+ }
}
}
} ),
@@ -937,8 +945,10 @@
if ( param == null || param.length() == 0 )
return _dateFormat.parse( (String) obj );
else {
- _paramDateFormat.applyPattern( param );
- return _paramDateFormat.parse( (String) obj );
+ synchronized (_paramDateFormat){
+ _paramDateFormat.applyPattern(param);
+ return _paramDateFormat.parse(
(String) obj );
+ }
}
} catch ( ParseException except ) {
throw new IllegalArgumentException( except.toString() );
@@ -948,8 +958,10 @@
new TypeConvertorInfo( new SQLTypeConvertor( java.lang.Integer.class,
java.util.Date.class ) {
public Object convert( Object obj, String param ) {
try {
- _paramDateFormat.applyPattern(
org.exolab.castor.mapping.loader.Types.getFullDatePattern( param ) );
- return _paramDateFormat.parse( obj.toString() );
+ synchronized (_paramDateFormat){
+
_paramDateFormat.applyPattern(org.exolab.castor.mapping.loader.Types.getFullDatePattern(
param ));
+ return _paramDateFormat.parse(
obj.toString() );
+ }
} catch ( ParseException except ) {
throw new IllegalArgumentException( except.toString() );
}
@@ -958,8 +970,10 @@
new TypeConvertorInfo( new SQLTypeConvertor( java.math.BigDecimal.class,
java.util.Date.class ) {
public Object convert( Object obj, String param ) {
try {
- _paramDateFormat.applyPattern(
org.exolab.castor.mapping.loader.Types.getFullDatePattern( param ) );
- return _paramDateFormat.parse( obj.toString() );
+ synchronized (_paramDateFormat){
+
_paramDateFormat.applyPattern(org.exolab.castor.mapping.loader.Types.getFullDatePattern(
param ));
+ return _paramDateFormat.parse(
obj.toString() );
+ }
} catch ( ParseException except ) {
throw new IllegalArgumentException( except.toString() );
}
@@ -968,8 +982,10 @@
new TypeConvertorInfo( new SQLTypeConvertor( java.lang.Double.class,
java.util.Date.class ) {
public Object convert( Object obj, String param ) {
try {
- _paramDateFormat.applyPattern(
org.exolab.castor.mapping.loader.Types.getFullDatePattern( param ) );
- return _paramDateFormat.parse( _decimalFormat.format(obj).trim()
);
+ synchronized (_paramDateFormat){
+
_paramDateFormat.applyPattern(org.exolab.castor.mapping.loader.Types.getFullDatePattern(
param ));
+ return _paramDateFormat.parse(
_decimalFormat.format(obj).trim() );
+ }
} catch ( ParseException except ) {
throw new IllegalArgumentException( except.toString() );
}
@@ -1017,8 +1033,10 @@
param = "yyyy-MM-dd HH:mm:ss.SSS";
}
try {
- _paramDateFormat.applyPattern( param );
- time = _paramDateFormat.parse( (String) obj ).getTime();
+ synchronized (_paramDateFormat){
+ _paramDateFormat.applyPattern(param);
+ time = _paramDateFormat.parse(
(String) obj ).getTime();
+ }
} catch ( ParseException except ) {
throw new IllegalArgumentException( except.toString() );
}
@@ -1034,8 +1052,10 @@
param = "yyyy-MM-dd HH:mm:ss.SSS";
}
java.sql.Timestamp timestamp = (java.sql.Timestamp) obj;
- _paramDateFormat.applyPattern( param );
- return _paramDateFormat.format( new
java.util.Date(timestamp.getTime() + timestamp.getNanos() / 1000000) );
+ synchronized (_paramDateFormat){
+ _paramDateFormat.applyPattern(param);
+ return _paramDateFormat.format( new
java.util.Date(timestamp.getTime() + timestamp.getNanos() / 1000000) );
+ }
}
} ),
// InputStream convertors