zhiqinghuang / lambdaj

Automatically exported from code.google.com/p/lambdaj
Apache License 2.0
0 stars 0 forks source link

Unable to convert the placeholder (due to garbage collection) #22

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1.create a memory consuming application so the garbage collector jumps in
quite often. 
2. do a lot (thousends) on(<someclass>.class).<someGetter>())
3. You get sometimes the error Unable to convert the placeholder <value of
the getter> in a valid argument

Debugging took me to the ArgumentsFactory.placeholderByInvocation. This is
a WeakHashMap, so things get GarbageCollected...
I'll try to debug further, but there is definately something wrong...

What version of the product are you using? On what operating system?
2.1

Original issue reported on code.google.com by pieter.d...@gmail.com on 10 Nov 2009 at 11:37

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
I think this is a not-so-easy-to-fix problem... It will be needed to 'unbind' 
the
arguments, but I don't see (yet) the right place to unbind them...

Original comment by pieter.d...@gmail.com on 10 Nov 2009 at 1:45

GoogleCodeExporter commented 8 years ago
The binding between the placeholder (the object returned by
on(<someclass>.class).<someGetter>() invocation) and the actual Argument is 
actually
made by another WeakHashMap in the same class named
ArgumentsFactory.argumentsByPlaceholder.

For how the WeakHashMap works, a weak entry in it could be removed by the 
garbage
collector only when the key (the placeholder in this case) is no longer 
referenced by
any other part of your code. It means that either there isn't any part of your
program that is holding a reference to the placeholder (and then you shouldn't 
be
able to use it anymore) or you are still referencing it somewhere and in this 
case
the garbage collector should not be allowed to remove it.

For the same reason hasn't been provided any method to 'unbind' an argument 
since (in
my intentions) this job should be delegated to the garbage collector when a
placeholder is no longer referenced (and then the relative argument is no longer
reachable).

If those assumptions are true and my design doesn't have any flaw you should 
never be
in the situation you are describing. But of course I cannot exclude that I am 
making
a subtle mistake here. So if you developed a test case that can reproduce the 
problem
you are reporting, it will be very helpful if you could send it to me so I could
figure out what is going wrong.

Thanks
Mario

Original comment by mario.fu...@gmail.com on 10 Nov 2009 at 2:04

GoogleCodeExporter commented 8 years ago
Thanks for the quick reply. I'm currently working on a testcase to reproduce 
it. Once
I've got it, you're the first to know :-)

Original comment by pieter.d...@gmail.com on 10 Nov 2009 at 2:11

GoogleCodeExporter commented 8 years ago
Ok. Be aware that you could obtain the same Exception in other two ways, totally
unrelated to the garbage collector work (and at the moment I believe there is a
bigger likelihood that you are in one of those cases):

1. you defined a placeholder of type boolean or enum in a thread and then you 
are
using it in a different thread.

or

2. you are misusing lambdaj by doing something similar to what described in the
second example of the known limitations page of the pdf presentation.

In order to not waste your time, please be sure that you are not in one of the 2
cases above. If you need more explanations about why these cases cannot work in
lambdaj feel free to write me again.

Original comment by mario.fu...@gmail.com on 10 Nov 2009 at 2:35

GoogleCodeExporter commented 8 years ago
Hmm, 

I think I've got it! I'm doing:
Object placeholder = on(Employee.class).getDate()
ArgumentsFactory.actualArgument(placeholder)

The returnType of getDate() is a org.joda.time.DateTime, and the DateTime is 
final. 
If I understand right, the Employee should not be final, but the returnType of 
it's
methods should not.. (correct?)

Still figuring out, why it sometime DOES work.... (but making the returnType
non-final sloves it .. (as far as I can see now...)

Original comment by pieter.d...@gmail.com on 10 Nov 2009 at 3:17

GoogleCodeExporter commented 8 years ago
I'm able to reproduce it.
Very weird: removing one of the System.gc() makes it work. 
making the dateTime non-final makes the test always green (with or without 
System.gc().

The attechment contains the test class (CouldNotCreateArgument) +  the DateTime 
class
to make final or not (note that you probably need the joda-time dependency (    

<dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>1.5</version>
        </dependency>
)

Original comment by pieter.d...@gmail.com on 10 Nov 2009 at 3:47

Attachments:

GoogleCodeExporter commented 8 years ago
It still doesn't seem to me that this problem could be related to the garbage
collector, but I need to investigate on it.
I will work on it and try to find an answer as soon as possible.
Thank you

Original comment by mario.fu...@gmail.com on 10 Nov 2009 at 4:13

GoogleCodeExporter commented 8 years ago
Thanks for your quick replys... It is a very strange behaviour... 
I'll investigate this also further. I'll keep you posted.

Thanks

Original comment by pieter.d...@gmail.com on 10 Nov 2009 at 4:26

GoogleCodeExporter commented 8 years ago
As I thought the problem you found was not related to the garbage collection.
I improved the heuristic used to create a placeholder for final classes and this
should fix your issue as well.

If you are able to download the last source code from the repository and make a 
build
of the project (I suppose it should be easy for you since you wrote in the bug 
report
that you are already using the release 2.1), please confirm if your problem is 
now
solved and if so I will close this ticket.

Thanks for your collaboration
Mario

Original comment by mario.fu...@gmail.com on 10 Nov 2009 at 11:16

GoogleCodeExporter commented 8 years ago

Original comment by mario.fu...@gmail.com on 10 Nov 2009 at 11:17

GoogleCodeExporter commented 8 years ago
I'll try to checkout the latest code asap, but today is a holiday in Belgium, 
so it
probably has to wait until tomorrow (or this evening maybe...)
Thanks for digging into this. 
I'll keep you posted.

Pieter

Original comment by pieter.d...@gmail.com on 11 Nov 2009 at 9:13

GoogleCodeExporter commented 8 years ago
I confirm that the problem is solved with the current snapshot.
When will this fix make it into a release? (since it is not a nice thing to have
snapshot versions in a production release ...

Thanks again for this great support and quick fix !

Pieter

Original comment by pieter.d...@gmail.com on 12 Nov 2009 at 8:54

GoogleCodeExporter commented 8 years ago
I will drop the release 2.1 by the end of this week.
If you are using lambdaj in some production environment could be great if you 
could
write a couple of sentences about your experience in the WhoIsUsingLambdaj wiki 
page.

Bye
Mario

Original comment by mario.fu...@gmail.com on 12 Nov 2009 at 9:04

GoogleCodeExporter commented 8 years ago
Perfect! (comment added :-) See you @ Devoxx ?)

Original comment by pieter.d...@gmail.com on 12 Nov 2009 at 10:31

GoogleCodeExporter commented 8 years ago
I am new to lambdaj, and start useing it for web server searching, 
I got same problem when searching, sorting doing quite often:

LambdaJMatcher matcher = Lambda.having(Lambda.on(Info.class).getId(), 
org.hamcrest.Matchers.anything());
matcher = input1 == null? matcher : 
matcher.and(Lambda.having(Lambda.on(Info.class).getInput1(), 
Matchers.greaterThanOrEqualTo(input1)));
matcher = input2 == null? matcher : 
matcher.and(Lambda.having(Lambda.on(Info.class).getInput2(), 
Matchers.greaterThanOrEqualTo(input2)));
...

Exception as shown below:
ch.lambdaj.function.argument.ArgumentConversionException: Unable to convert the 
placeholder -2.14748365E9 in a valid argument
        at ch.lambdaj.function.argument.ArgumentsFactory.actualArgument(ArgumentsFactory.java:78)
        at ch.lambdaj.function.matcher.HasArgumentWithValue.havingValue(HasArgumentWithValue.java:70)
        at ch.lambdaj.Lambda.having(Lambda.java:1068)

Original comment by poo...@gmail.com on 30 Jul 2010 at 4:22

GoogleCodeExporter commented 8 years ago
I am afraid I miss some important info in order to figure out what causes the 
problem you are experiencing:

1. Which version of lambdaj are you using?
2. How the Info class is made?
3. Could you send some more code or even better a complete test case in order 
to allow me to reproduce this problem?

Thanks a lot
Mario

Original comment by mario.fu...@gmail.com on 30 Jul 2010 at 7:03

GoogleCodeExporter commented 8 years ago
I am using the laterest 2.3 version
and attached some code

Original comment by poo...@gmail.com on 16 Aug 2010 at 2:38

Attachments:

GoogleCodeExporter commented 8 years ago
This problem has been already reported in issue #33 and will be fixed with the 
release 2.3.1

Original comment by mario.fu...@gmail.com on 16 Aug 2010 at 7:47

GoogleCodeExporter commented 8 years ago
im using 2.4 and this issue still exists..

ch.lambdaj.function.argument.ArgumentConversionException: Unable to convert the 
placeholder null in a valid argument
    at ch.lambdaj.function.argument.ArgumentsFactory.actualArgument(ArgumentsFactory.java:92)
    at ch.lambdaj.function.matcher.HasArgumentWithValue.havingValue(HasArgumentWithValue.java:70)
    at ch.lambdaj.Lambda.having(Lambda.java:1204)
    at com.numbeez.api.test.UserControllerUnitTests.topForUser(UserControllerUnitTests.java:122)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:68)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:300)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

Original comment by o...@numbeez.com on 16 Aug 2012 at 10:31

GoogleCodeExporter commented 8 years ago
yep, it doesn't seem to be resolved in 2.4

Original comment by zazi0...@googlemail.com on 7 Nov 2012 at 1:25