| Author |
Message |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 05/30/2007 03:59:43
|
mpvvliet
neo
Joined: 05/30/2007 03:52:01
Messages: 2
Offline
|
Hi all,
we are trying to cluster our application using TC. The application uses the joda-time library to represent dates. This library seems to have a lot of transient data, so to make it work we set the honor transient flag to false for joda-time classes. However, this leads to the following error:
Code:
java.lang.ClassCastException: ReadablePartial objects must have matching field types
at org.joda.time.base.AbstractPartial.compareTo(AbstractPartial.java:325)
at nl.prorail.pub.dvs.TrainDepartureMessage.compareTo(TrainDepartureMessage.java:127)
at nl.prorail.pub.dvs.TrainDepartureMessage.compareTo(TrainDepartureMessage.java:31)
at java.util.Arrays.mergeSort(Arrays.java:1156)
at java.util.Arrays.sort(Arrays.java:1080)
at java.util.Collections.sort(Collections.java:117)
at nl.prorail.pub.display.Tb7xController.createPublications(Tb7xController.java:90)
at nl.prorail.pub.display.Tb7xController.messageReceived(Tb7xController.java:79)
at nl.prorail.pub.dvs.TrainDepartureMessage.accept(TrainDepartureMessage.java:363)
at nl.prorail.pub.display.DisplayController.messageReceived(DisplayController.java:33)
at nl.prorail.pub.distribution.Station.messageReceived(Station.java:31)
at nl.prorail.pub.service.PubServiceImpl.messageReceived(PubServiceImpl.java:40)
at nl.prorail.pub.service.DvsMessageListener.onMessage(DvsMessageListener.java:45)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doInvokeListener(AbstractMessageListenerContainer.java:854)
at org.springframework.jms.listener.AbstractMessageListenerContainer.invokeListener(AbstractMessageListenerContainer.java:793)
at org.springframework.jms.listener.AbstractMessageListenerContainer.doExecuteListener(AbstractMessageListenerContainer.java:763)
at org.springframework.jms.listener.DefaultMessageListenerContainer.doReceiveAndExecute(DefaultMessageListenerContainer.java:513)
at org.springframework.jms.listener.DefaultMessageListenerContainer.receiveAndExecute(DefaultMessageListenerContainer.java:460)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:871)
at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:824)
at org.springframework.core.task.SimpleAsyncTaskExecutor$ConcurrencyThrottlingRunnable.run(SimpleAsyncTaskExecutor.java:203)
at java.lang.Thread.run(Thread.java:595)
Honoring transient leads to NPE's so this is also not an option. A custom on-load element might work, but we haven't found the right way to (re)initialize these fields yet.
Has anyone gotten TC to work with joda-time? Any help would be appreciated.
Thanks,
Martin
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 05/30/2007 23:32:06
|
kbhasin
consul
Joined: 12/04/2006 13:08:21
Messages: 340
Offline
|
Hi mpvvliet,
I am not sure if anyone has tried to cluster joda-time with Terracotta.
Are you getting this error on a single node or on multiple nodes?
I think what you are seeing here is that when the compareTo is called to compare the ReadablePartial implementation (some sub-class of AbstractPartial), the transient field value is null (on the second instance) and hence the resulting "field types must match" error.
The correct way to handle this would be to honor transient and use an appropriate method (e.g. bean shell) to initialize transients on the onLoad:
Code:
<class-expression>com.mycompany.mypackage.MyClass</class-expression>
<!-- If set to 'true', then any fields in the given class(es)
that have the Java 'transient' modifier are not shared
across JVMs. If set to 'false', they are.
Default: false -->
<honor-transient>true</honor-transient>
<on-load>
<!-- One of either <execute> or <method> is required within an <on-load> element -->
<!-- This (zero argument) method will be called on instances of the specified class
on load of the object. Used to intialize transient fields. You are free to use
whatever method name you please. -->
<!-- <method>initTransients</method> -->
<!-- This bean shell script is called right after an object is loaded -->
<execute><![CDATA[self.myTransientField = new ArrayList();]]></execute>
</on-load>
</include>
Can you also point to the subclass of AbstractPartial in question here. I am assuming it should be one of the following:
class LocalDate
LocalDate is an immutable datetime class representing a date without a time zone.
class LocalDateTime
LocalDateTime is an unmodifiable datetime class representing a datetime without a time zone.
class LocalTime
LocalTime is an immutable time class representing a time without a time zone.
class Partial
Partial is an immutable partial datetime supporting any set of datetime fields.
class TimeOfDay
TimeOfDay is an immutable partial supporting the hour, minute, second and millisecond fields.
class YearMonthDay
YearMonthDay is an immutable partial supporting the year, monthOfYear and dayOfMonth fields.
Regards,
Kunal Bhasin.
|
Regards,
Kunal Bhasin,
Terracotta, Inc.
Be a part of the Terracotta community: Join now! |
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 06/01/2007 01:24:54
|
mpvvliet
neo
Joined: 05/30/2007 03:52:01
Messages: 2
Offline
|
Hi Kunal.
it is an instance of the LocalTime class. I have tested this only with 1 node. After processing some data, the TC server holds the clustered instances. Then I restart the node and the application attempts to retrieve & modify the data contained in TC. This is when the error occurs. I assume the same will happen with 2 nodes when they share data, but I have not verified this.
I tried calling a Beanshell initialization method (setFields()) like so:
Code:
<include>
<class-expression>org.joda.time.chrono.AssembledChronology</class-expression>
<honor-transient>true</honor-transient>
<on-load>
<execute>self.setFields();</execute>
</on-load>
</include>
but this did not fix anything, the same error still occurred. Perhaps I am using the wrong BS syntax?
Regards,
Martin
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 06/01/2007 09:41:30
|
kbhasin
consul
Joined: 12/04/2006 13:08:21
Messages: 340
Offline
|
Hi Martin,
Can you try the following syntax:
Code:
<on-load>
<!-- This bean shell script is called right after an object is loaded -->
<execute><![CDATA[self.myTransientField = new ArrayList();]]></execute>
</on-load>
If you have access to code, you can also add a custom method in your code to initialize transients:
Code:
<on-load>
<!-- This (zero argument) method will be called on instances of the specified class
on load of the object. Used to intialize transient fields. You are free to use
whatever method name you please. -->
<method>initTransients</method>
<!-- e.g. The method in your code would look like this -
public void initTransients() {
myTransientField = new ArrayList();
}
-->
</on-load>
Also, the <on-load> property should be paired with the <include> of the class containing the transient field or a wildcard [ e.g. mypackage..* ] that includes the class containing the transient.
In your case, I am not sure if it wil be LocalTime or AssembledChronology.
Regards,
Kunal Bhasin.
|
Regards,
Kunal Bhasin,
Terracotta, Inc.
Be a part of the Terracotta community: Join now! |
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 02/19/2008 11:12:39
|
Shake
master
Joined: 01/05/2008 07:27:49
Messages: 84
Offline
|
Okay, I run into the same problem.
I tried
Code:
<include> <class-expression>org.joda.time.chrono.AssembledChronology</class-expression>
<honor-transient>true</honor-transient>
<on-load>
<execute><![CDATA[self.setFields();]]></execute>
</on-load>
</include>
which doesn't solve my problem. Any hints? Had anyone success using Joda Time and Terracotta?
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 02/19/2008 11:44:36
|
Shake
master
Joined: 01/05/2008 07:27:49
Messages: 84
Offline
|
Investigated further:
There seems to exist a problem with object identity.
At org.joda.time.base.AbstractPartial.compareTo(AbstractPartial.java:325)
there are tow org.joda.time.DateTimeFieldType compared using "!=".
I don't know why this fails - but while the fields represent the same thing (month, year...) they have lost the object identity...
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 02/19/2008 13:01:13
|
Shake
master
Joined: 01/05/2008 07:27:49
Messages: 84
Offline
|
Okay, I have found a solution:
Code:
<roots>
<root>
<field-name>org.joda.time.DateTimeFieldType.ERA_TYPE</field-name>
</root>
<root>
<field-name>org.joda.time.DateTimeFieldType.YEAR_OF_ERA_TYPE</field-name>
</root>
<root>
<field-name>org.joda.time.DateTimeFieldType.CENTURY_OF_ERA_TYPE</field-name>
</root>
Since I could't find a valid field-expression, I had to add every single field...
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 02/19/2008 13:17:08
|
tgautier
seraphim
Joined: 06/05/2006 12:19:26
Messages: 1781
Offline
|
Neat. When you have a working prototype, maybe you would like some help turning it into a TIM?
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 02/19/2008 13:59:37
|
Shake
master
Joined: 01/05/2008 07:27:49
Messages: 84
Offline
|
And one more issue: The method org.joda.time.tz.CachedDateTimeZone#getInfo is not synchronized, but I think it should be (for terracotta).
I tried to add a named lock, but this didn't work as expected... Either I defined the named lock wrong or adding the lock doesn't solve the issue.
Same goes for org.joda.time.chrono.BasicChronology#getYearInfo.
Could you provide give me a hint how a name lock should look like? And show an example of the field-expression that matches all the static fields of a given type within a given class?
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 02/19/2008 14:03:41
|
ekulesho
master
Joined: 12/04/2006 08:49:08
Messages: 57
Offline
|
Shake wrote:
... Since I could't find a valid field-expression, I had to add every single field...
Documentation for the expression language is here. So you can try something like this:
Code:
<field-expression>* org.joda.time.DateTimeFieldType org.joda.time.DateTimeFieldType.*</field-expression>
regards,
Eugene Kuleshov
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 02/19/2008 14:08:10
|
Shake
master
Joined: 01/05/2008 07:27:49
Messages: 84
Offline
|
Yes, tried that already:
Code:
[INFO] [bootjar] com.tc.aspectwerkz.exception.DefinitionException: expression is not well-formed [get(* org.joda.time.DateTimeFieldType org.joda.time.DateTimeFieldType.*)]: Encountered "org.joda.time.DateTimeFieldType.*" at line 1, column 39.
[INFO] [bootjar] Was expecting:
[INFO] [bootjar] ")" ...
[INFO] [bootjar]
[INFO] [bootjar] at com.tc.aspectwerkz.expression.ExpressionInfo.<init>(ExpressionInfo.java:92)
[INFO] [bootjar] at com.tc.object.bytecode.aspectwerkz.ExpressionHelper.createExpressionInfo(ExpressionHelper.java:61)
[INFO] [bootjar] at com.tc.object.bytecode.aspectwerkz.ExpressionHelper.createExpressionInfo(ExpressionHelper.java:49)
[INFO] [bootjar] at com.tc.object.bytecode.aspectwerkz.ExpressionHelper.createExpressionVisitor(ExpressionHelper.java:41)
[INFO] [bootjar] at com.tc.object.config.Root.matches(Root.java:93)
[INFO] [bootjar] at com.tc.object.config.StandardDSOClientConfigHelperImpl.findMatchingRootDefinition(StandardDSOClientConfigHelperImpl.java:1232)
[INFO] [bootjar] at com.tc.object.config.StandardDSOClientConfigHelperImpl.classContainsAnyRoots(StandardDSOClientConfigHelperImpl.java:1241)
[INFO] [bootjar] at com.tc.object.config.StandardDSOClientConfigHelperImpl.shouldBeAdapted(StandardDSOClientConfigHelperImpl.java:1437)
[INFO] [bootjar] at com.tc.object.config.TransparencyClassSpecImpl.hasPhysicallyPortableSpecs(TransparencyClassSpecImpl.java:88)
[INFO] [bootjar] at com.tc.object.bytecode.InstrumentationSpec.isNeedManagedField(InstrumentationSpec.java:238)
[INFO] [bootjar] at com.tc.object.bytecode.InstrumentationSpec.decideOnInstrumentationsToDo(InstrumentationSpec.java:223)
[INFO] [bootjar] at com.tc.object.bytecode.InstrumentationSpec.decideOnInstrumentationAction(InstrumentationSpec.java:212)
[INFO] [bootjar] at com.tc.object.bytecode.InstrumentationSpec.initialize(InstrumentationSpec.java:121)
[INFO] [bootjar] at com.tc.object.bytecode.ClassAdapterBase.visit(ClassAdapterBase.java:105)
[INFO] [bootjar] at com.tc.object.bytecode.MergeTCToJavaClassAdapter.visit(MergeTCToJavaClassAdapter.java:129)
[INFO] [bootjar] at com.tc.asm.ClassAdapter.visit(ClassAdapter.java:63)
[INFO] [bootjar] at com.tc.asm.commons.SerialVersionUIDAdder.visit(SerialVersionUIDAdder.java:199)
[INFO] [bootjar] at com.tc.asm.ClassReader.accept(ClassReader.java:553)
[INFO] [bootjar] at com.tc.asm.ClassReader.accept(ClassReader.java:420)
[INFO] [bootjar] at com.tc.object.tools.BootJarTool.mergeClass(BootJarTool.java:2208)
[INFO] [bootjar] at com.tc.object.tools.BootJarTool.mergeClass(BootJarTool.java:2165)
[INFO] [bootjar] at com.tc.object.tools.BootJarTool.addInstrumentedHashMap(BootJarTool.java:2159)
[INFO] [bootjar] at com.tc.object.tools.BootJarTool.generateJar(BootJarTool.java:402)
[INFO] [bootjar] at com.tc.object.tools.BootJarTool.main(BootJarTool.java:2532)
[INFO] [bootjar] com.tc.aspectwerkz.expression.ast.ParseException: Encountered "org.joda.time.DateTimeFieldType.*" at line 1, column 39.
[INFO] [bootjar] Was expecting:
[INFO] [bootjar] ")" ...
[INFO] [bootjar]
[INFO] [bootjar] at com.tc.aspectwerkz.expression.ast.ExpressionParser.generateParseException(ExpressionParser.java:3521)
[INFO] [bootjar] at com.tc.aspectwerkz.expression.ast.ExpressionParser.jj_consume_token(ExpressionParser.java:3391)
[INFO] [bootjar] at com.tc.aspectwerkz.expression.ast.ExpressionParser.Get(ExpressionParser.java:739)
[INFO] [bootjar] at com.tc.aspectwerkz.expression.ast.ExpressionParser.Pointcut(ExpressionParser.java:315)
[INFO] [bootjar] at com.tc.aspectwerkz.expression.ast.ExpressionParser.UnaryExpression(ExpressionParser.java:246)
[INFO] [bootjar] at com.tc.aspectwerkz.expression.ast.ExpressionParser.OrExpression(ExpressionParser.java:177)
[INFO] [bootjar] at com.tc.aspectwerkz.expression.ast.ExpressionParser.AndExpression(ExpressionParser.java:131)
[INFO] [bootjar] at com.tc.aspectwerkz.expression.ast.ExpressionParser.Expression(ExpressionParser.java:93)
[INFO] [bootjar] at com.tc.aspectwerkz.expression.ast.ExpressionParser.Root(ExpressionParser.java:49)
[INFO] [bootjar] at com.tc.aspectwerkz.expression.ast.ExpressionParser.parse(ExpressionParser.java:35)
[INFO] [bootjar] at com.tc.aspectwerkz.expression.ast.ExpressionParser.parse(ExpressionParser.java:30)
[INFO] [bootjar] at com.tc.aspectwerkz.expression.ExpressionInfo.<init>(ExpressionInfo.java:85)
[INFO] [bootjar] at com.tc.object.bytecode.aspectwerkz.ExpressionHelper.createExpressionInfo(ExpressionHelper.java:61)
[INFO] [bootjar] at com.tc.object.bytecode.aspectwerkz.ExpressionHelper.createExpressionInfo(ExpressionHelper.java:49)
[INFO] [bootjar] at com.tc.object.bytecode.aspectwerkz.ExpressionHelper.createExpressionVisitor(ExpressionHelper.java:41)
[INFO] [bootjar] at com.tc.object.config.Root.matches(Root.java:93)
[INFO] [bootjar] at com.tc.object.config.StandardDSOClientConfigHelperImpl.findMatchingRootDefinition(StandardDSOClientConfigHelperImpl.java:1232)
[INFO] [bootjar] at com.tc.object.config.StandardDSOClientConfigHelperImpl.classContainsAnyRoots(StandardDSOClientConfigHelperImpl.java:1241)
[INFO] [bootjar] at com.tc.object.config.StandardDSOClientConfigHelperImpl.shouldBeAdapted(StandardDSOClientConfigHelperImpl.java:1437)
[INFO] [bootjar] at com.tc.object.config.TransparencyClassSpecImpl.hasPhysicallyPortableSpecs(TransparencyClassSpecImpl.java:88)
[INFO] [bootjar] at com.tc.object.bytecode.InstrumentationSpec.isNeedManagedField(InstrumentationSpec.java:238)
[INFO] [bootjar] at com.tc.object.bytecode.InstrumentationSpec.decideOnInstrumentationsToDo(InstrumentationSpec.java:223)
[INFO] [bootjar] at com.tc.object.bytecode.InstrumentationSpec.decideOnInstrumentationAction(InstrumentationSpec.java:212)
[INFO] [bootjar] at com.tc.object.bytecode.InstrumentationSpec.initialize(InstrumentationSpec.java:121)
[INFO] [bootjar] at com.tc.object.bytecode.ClassAdapterBase.visit(ClassAdapterBase.java:105)
[INFO] [bootjar] at com.tc.object.bytecode.MergeTCToJavaClassAdapter.visit(MergeTCToJavaClassAdapter.java:129)
[INFO] [bootjar] at com.tc.asm.ClassAdapter.visit(ClassAdapter.java:63)
[INFO] [bootjar] at com.tc.asm.commons.SerialVersionUIDAdder.visit(SerialVersionUIDAdder.java:199)
[INFO] [bootjar] at com.tc.asm.ClassReader.accept(ClassReader.java:553)
[INFO] [bootjar] at com.tc.asm.ClassReader.accept(ClassReader.java:420)
[INFO] [bootjar] at com.tc.object.tools.BootJarTool.mergeClass(BootJarTool.java:2208)
[INFO] [bootjar] at com.tc.object.tools.BootJarTool.mergeClass(BootJarTool.java:2165)
[INFO] [bootjar] at com.tc.object.tools.BootJarTool.addInstrumentedHashMap(BootJarTool.java:2159)
[INFO] [bootjar] at com.tc.object.tools.BootJarTool.generateJar(BootJarTool.java:402)
[INFO] [bootjar] at com.tc.object.tools.BootJarTool.main(BootJarTool.java:2532)
[INFO] [bootjar]
[INFO] [bootjar] *************** ERROR ***************
[INFO] [bootjar] * ERROR creating temp boot jar
[INFO] [bootjar] *************************************
[INFO] [bootjar]
for
Code:
<roots>
<root>
<field-expression>* org.joda.time.DateTimeFieldType org.joda.time.DateTimeFieldType.*</field-expression>
<root-name>theName</root-name>
</root>
</roots>
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 02/19/2008 14:27:59
|
tgautier
seraphim
Joined: 06/05/2006 12:19:26
Messages: 1781
Offline
|
Shake wrote:
And one more issue: The method org.joda.time.tz.CachedDateTimeZone#getInfo is not synchronized, but I think it should be (for terracotta).
Maybe an auto-synchronized would be better:
Code:
<autolock auto-synchronized="true">
<method-expression>* org.joda.time.tz.CachedDateTimeZone.getInfo(..)</method-expression>
</autolock>
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 02/19/2008 14:29:40
|
tgautier
seraphim
Joined: 06/05/2006 12:19:26
Messages: 1781
Offline
|
ekulesho wrote:
Shake wrote:
... Since I could't find a valid field-expression, I had to add every single field...
Documentation for the expression language is here. So you can try something like this:
Code:
<field-expression>* org.joda.time.DateTimeFieldType org.joda.time.DateTimeFieldType.*</field-expression>
regards,
Eugene Kuleshov
This would work if you want every field in DateTimeFieldType - however if there are fields that shouldn't be roots this might be over-broad.
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 02/19/2008 14:31:20
|
tgautier
seraphim
Joined: 06/05/2006 12:19:26
Messages: 1781
Offline
|
Shake wrote:
Yes, tried that already:
for
Code:
<roots>
<root>
<field-expression>* org.joda.time.DateTimeFieldType org.joda.time.DateTimeFieldType.*</field-expression>
<root-name>theName</root-name>
</root>
</roots>
Hmm, I think the root-name would try to make all of the fields the same root, which would be bad (basically they would all be forced to be the same object). That *should* work if you take the root-name spec out, however as I say in my previous post, only if you want every field in DateTimeFieldType to be a root.
|
|
|
 |
![[Post New]](/forums/templates/default/images/icon_minipost_new.gif) 02/19/2008 14:39:25
|
ekulesho
master
Joined: 12/04/2006 08:49:08
Messages: 57
Offline
|
Shake wrote:
Yes, tried that already:Code:
<roots>
<root>
<field-expression>* org.joda.time.DateTimeFieldType org.joda.time.DateTimeFieldType.*</field-expression>
<root-name>theName</root-name>
</root>
</roots>
Indeed. It seems like parser doesn't like when * is used in the modifiers slot. I've tried this variant and it is at least accepted by the expression parser:
Code:
<field-expression>private static final org.joda.time.DateTimeFieldType org.joda.time.DateTimeFieldType.*</field-expression>
regards,
Eugene Kuleshov
|
|
|
 |
|
|