If I add a new attribute to a class, its value is stored fine.
But, if I thereafter add another value for the same attribute, this value is added twice.
I encountered this with Jetspeed-2 ldap unit tests, but could then easily reproduce this with for instance LDAP Browser\Editor v.2.8.2
Description
If I add a new attribute to a class, its value is stored fine.
But, if I thereafter add another value for the same attribute, this value is added twice.
I encountered this with Jetspeed-2 ldap unit tests, but could then easily reproduce this with for instance LDAP Browser\Editor v.2.8.2
I am not able to reproduce this error. We need more information.
Please check the attached test case. It creates an entry with a description and adds two other description values. Afterwards the entry looks like it should:
$ ldapsearch -D "uid=admin,ou=system" -w ***** -p 10389 -s one -b "dc=example,dc=com" "(cn=Fiona Apple)"
dn: cn=Fiona Apple,dc=example,dc=com
description: an American singer-songwriter
description: Grammy award winning
description: MTV Music Award winning
objectclass: person
objectclass: top
sn: Apple
cn: Fiona Apple
Stefan Zoerner added a comment - 19/Nov/06 08:09 AM I am not able to reproduce this error. We need more information.
Please check the attached test case. It creates an entry with a description and adds two other description values. Afterwards the entry looks like it should:
$ ldapsearch -D "uid=admin,ou=system" -w ***** -p 10389 -s one -b "dc=example,dc=com" "(cn=Fiona Apple)"
dn: cn=Fiona Apple,dc=example,dc=com
description: an American singer-songwriter
description: Grammy award winning
description: MTV Music Award winning
objectclass: person
objectclass: top
sn: Apple
cn: Fiona Apple
What is the difference in your situation?
At first, I couldn't reproduce the problem with your testcase until I made a small modification.
In your testcase your create the entry with the description attribute and then add 2 more values.
But, if you first create the entry *without* the description attribute and thereafter add the three values for the description attribute, the problem surfaces:
junit.framework.AssertionFailedError: expected:<3> but was:<5>
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.failNotEquals(Assert.java:282)
at junit.framework.Assert.assertEquals(Assert.java:64)
at junit.framework.Assert.assertEquals(Assert.java:201)
at junit.framework.Assert.assertEquals(Assert.java:207)
at add.AddingAnotherValueToAnAttribute.testAddAnotherValueToAnAttribute(AddingAnotherValueToAnAttribute.java:100)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
I've attached the modified testcase as well as the apacheds-stdout.log which clearly shows what happened.
I also noticed the apacheds-stderr.log contains two error messages: "jsvc.exec error: syscall failed in set_caps"
Maybe that's related to this issue?
Finally, for completeness, this is the ldif export after the testcase:
dn: dc=example,dc=com
dc: example
objectclass: top
objectclass: domain
objectclass: extensibleObject
dn: cn=Fiona Apple, dc=example,dc=com
objectclass: person
objectclass: top
description: an American singer-songwriter
description: Grammy award winning
description: Grammy award winning
description: MTV Music Award winning
description: MTV Music Award winning
sn: Apple
cn: Fiona Apple
Hopefully you will be able to reproduce this problem now too.
Ate Douma added a comment - 19/Nov/06 03:27 PM Thanks for following up Stefan.
At first, I couldn't reproduce the problem with your testcase until I made a small modification.
In your testcase your create the entry with the description attribute and then add 2 more values.
But, if you first create the entry *without* the description attribute and thereafter add the three values for the description attribute, the problem surfaces:
junit.framework.AssertionFailedError: expected:<3> but was:<5>
at junit.framework.Assert.fail(Assert.java:47)
at junit.framework.Assert.failNotEquals(Assert.java:282)
at junit.framework.Assert.assertEquals(Assert.java:64)
at junit.framework.Assert.assertEquals(Assert.java:201)
at junit.framework.Assert.assertEquals(Assert.java:207)
at add.AddingAnotherValueToAnAttribute.testAddAnotherValueToAnAttribute(AddingAnotherValueToAnAttribute.java:100)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.junit3.JUnit3TestReference.run(JUnit3TestReference.java:128)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
I've attached the modified testcase as well as the apacheds-stdout.log which clearly shows what happened.
I also noticed the apacheds-stderr.log contains two error messages: "jsvc.exec error: syscall failed in set_caps"
Maybe that's related to this issue?
Finally, for completeness, this is the ldif export after the testcase:
dn: dc=example,dc=com
dc: example
objectclass: top
objectclass: domain
objectclass: extensibleObject
dn: cn=Fiona Apple, dc=example,dc=com
objectclass: person
objectclass: top
description: an American singer-songwriter
description: Grammy award winning
description: Grammy award winning
description: MTV Music Award winning
description: MTV Music Award winning
sn: Apple
cn: Fiona Apple
Hopefully you will be able to reproduce this problem now too.
Stefan Zoerner added a comment - 19/Nov/06 04:03 PM Yes, I can confirm the problem. It is definitely an error within our software.
Thanks for the modified test case and the detailed information. Stefan
Alex Karasulu added a comment - 03/Dec/06 03:24 PM Increasing severity. I'd say this is a pretty critical bug that needs to be zapped right away in a 1.0.1.
Ok, the problem has been insolated. When we ask for a modification of an entry, we do the following operations :
1) in SchemaService, we clone the entry
2) then we apply the modification on the clone, to check that the modification is acceptable
3) we go down the interceptor chain to EventService where we get again the original entry (the clone has been ditched)
4) in JdbmBackend, we finally apply the modification.
But at thsi point, the clone is still alive, and as stated by Java doco of Basic Attribute.clone() :
"Makes a copy of the attribute. The copy contains the same attribute values as the original attribute: the attribute values are not themselves cloned"
Emmanuel Lecharny added a comment - 05/Jan/07 08:14 PM Ok, the problem has been insolated. When we ask for a modification of an entry, we do the following operations :
1) in SchemaService, we clone the entry
2) then we apply the modification on the clone, to check that the modification is acceptable
3) we go down the interceptor chain to EventService where we get again the original entry (the clone has been ditched)
4) in JdbmBackend, we finally apply the modification.
But at thsi point, the clone is still alive, and as stated by Java doco of Basic Attribute.clone() :
"Makes a copy of the attribute. The copy contains the same attribute values as the original attribute: the attribute values are not themselves cloned"
So we are in a bad position here ...
We gonna find a workaround.
Fix DIRSERVER-783. Ok, I admit this is a *huge* commit.
Basically, here are the modification
- get rid of BasicAttribute(s), and replace them by Attribute(s)Impl
- renamed LockableAttribute(s)Impl to Attribute(s)Impl
- created a new ModificationItemImpl which extends ModificationItem for cloning purpose
- added a test for DIRSERVER-783
- fixed the way Attribute(s) are cloned
- fixed a lot of other errors in Attribute(s)Impl (mainly special cases)
- added more utility methods in AttributeUtils
- removed all the import javax.naming.directory.* all over the code (Please, do _not_ use * in imports !!!)
Patch for DIRSERVER-783.
- No more BasicAttribute and BasicAttributes. Use AttributeImpl and AttributesImpl now.
- No more ModificationItem. use ModificationItemImpl now
- lot of refactoring of imports : no more import xxx.*;
Patch for DIRSERVER-783.
- No more BasicAttribute and BasicAttributes. Use AttributeImpl and AttributesImpl now.
- No more ModificationItem. use ModificationItemImpl now
- lot of refactoring of imports : no more import xxx.*;
Patch for DIRSERVER-783.
- No more BasicAttribute and BasicAttributes. Use AttributeImpl and AttributesImpl now.
- No more ModificationItem. use ModificationItemImpl now
- lot of refactoring of imports : no more import xxx.*;
Patch for DIRSERVER-783.
- No more BasicAttribute and BasicAttributes. Use AttributeImpl and AttributesImpl now.
- No more ModificationItem. use ModificationItemImpl now
- lot of refactoring of imports : no more import xxx.*;
Patch for DIRSERVER-783.
- No more BasicAttribute and BasicAttributes. Use AttributeImpl and AttributesImpl now.
- No more ModificationItem. use ModificationItemImpl now
- lot of refactoring of imports : no more import xxx.*;
Patch for DIRSERVER-783.
- No more BasicAttribute and BasicAttributes. Use AttributeImpl and AttributesImpl now.
- No more ModificationItem. use ModificationItemImpl now
- lot of refactoring of imports : no more import xxx.*;
Patch for DIRSERVER-783.
- No more BasicAttribute and BasicAttributes. Use AttributeImpl and AttributesImpl now.
- No more ModificationItem. use ModificationItemImpl now
- lot of refactoring of imports : no more import xxx.*;
Patch for DIRSERVER-783.
- No more BasicAttribute and BasicAttributes. Use AttributeImpl and AttributesImpl now.
- No more ModificationItem. use ModificationItemImpl now
- lot of refactoring of imports : no more import xxx.*;
Patch for DIRSERVER-783.
- No more BasicAttribute and BasicAttributes. Use AttributeImpl and AttributesImpl now.
- No more ModificationItem. use ModificationItemImpl now
- lot of refactoring of imports : no more import xxx.*;
Patch for DIRSERVER-783.
- No more BasicAttribute and BasicAttributes. Use AttributeImpl and AttributesImpl now.
- No more ModificationItem. use ModificationItemImpl now
- lot of refactoring of imports : no more import xxx.*;
Patch for DIRSERVER-783.
- No more BasicAttribute and BasicAttributes. Use AttributeImpl and AttributesImpl now.
- No more ModificationItem. use ModificationItemImpl now
- lot of refactoring of imports : no more import xxx.*;
Patch for DIRSERVER-783.
- No more BasicAttribute and BasicAttributes. Use AttributeImpl and AttributesImpl now.
- No more ModificationItem. use ModificationItemImpl now
- lot of refactoring of imports : no more import xxx.*;
Patch for DIRSERVER-783.
- No more BasicAttribute and BasicAttributes. Use AttributeImpl and AttributesImpl now.
- No more ModificationItem. use ModificationItemImpl now
- lot of refactoring of imports : no more import xxx.*;
Patch for DIRSERVER-783.
- No more BasicAttribute and BasicAttributes. Use AttributeImpl and AttributesImpl now.
- No more ModificationItem. use ModificationItemImpl now
- lot of refactoring of imports : no more import xxx.*;
Patch for DIRSERVER-783.
- No more BasicAttribute and BasicAttributes. Use AttributeImpl and AttributesImpl now.
- No more ModificationItem. use ModificationItemImpl now
- lot of refactoring of imports : no more import xxx.*;
Patch for DIRSERVER-783.
- No more BasicAttribute and BasicAttributes. Use AttributeImpl and AttributesImpl now.
- No more ModificationItem. use ModificationItemImpl now
- lot of refactoring of imports : no more import xxx.*;
Please check the attached test case. It creates an entry with a description and adds two other description values. Afterwards the entry looks like it should:
$ ldapsearch -D "uid=admin,ou=system" -w ***** -p 10389 -s one -b "dc=example,dc=com" "(cn=Fiona Apple)"
dn: cn=Fiona Apple,dc=example,dc=com
description: an American singer-songwriter
description: Grammy award winning
description: MTV Music Award winning
objectclass: person
objectclass: top
sn: Apple
cn: Fiona Apple
What is the difference in your situation?