Couldn't find a differ for type: [Ljava.lang.String;
docfirefly opened this issue · 10 comments
How can I handle following error message:
Caused by: java.lang.IllegalStateException: Couldn't find a differ for type: [Ljava.lang.String;
Thanks
You are trying to diff an array of strings. Arrays are currently not supported out-of-the-box. Sorry about that.
However, you have a couple of options:
- The easy, but most invasive way: use either a
ListorSetinstead of anArray. - The not so easy, but most flexible way: implement a custom
Differthat's capable of handling string arrays or arrays in general. Since you only need to consider your own use case, it could be a pretty simple implementation. Small caveat: I've yet to try to write such a differ without being able to make changes to the core. So you may or may not hit some obstacles, which require a little work on the core. - You could also try to create a wrapper object that's optimized for diffing and does the same as 1.) but in a non-invasive way.
Bonus option: if you don't care about the problematic property, you can simply instruct the object differ to ignore it.
Ok thank you for your fast reply.
I guess I cannot use option 1 and 3 because there are too many classes involved and I am not the owner of them. The easiest way would be to ignore them but I am not sure if they are important (the project is in planning stage at the moment).
And I ve already thought about option 2 and tried it but as you mentionend it wasnt so easy for me ;)
Do you have any idea when version 0.93 or even better 1.0 will be released?
I currently don't have much spare time at my hands, so I can't make any promises. Although I do want to eventually add proper array-support, I can't tell you when I'll get to it. But if you can name a few of the things keeping you from implementing your own differ, I may be able to make some quick changes to get those issues out of the way.
Ok, so far I haven't started to implement my own differ. The project planning state isn't completed atm. If I need furthter help I will contact you - Thanks!
Closing this for now. Feel free to reopen if anything new comes up.
You can try with my little trick :)
public class ArrayDiffer implements Differ {
private static final Logger LOG = LoggerFactory.getLogger(ArrayDiffer.class);
private final CollectionDiffer collectionDiffer;
public ArrayDiffer(DifferDispatcher differDispatcher, ObjectDifferBuilder objectDifferBuilder) {
collectionDiffer = new CollectionDiffer(differDispatcher, (ComparisonService) objectDifferBuilder.comparison(), objectDifferBuilder.identity());
}
@Override
public boolean accepts(Class<?> type) {
return !type.isPrimitive() && type.isArray();
}
@Override
public DiffNode compare(DiffNode parentNode, Instances instances) {
final Object[] workings = (Object[]) instances.getWorking();
final Object[] bases = (Object[]) instances.getBase();
Instances instances1 = Instances.of(instances.getSourceAccessor(),
Arrays.asList(workings),
Arrays.asList(bases),
instances.getFresh());
return collectionDiffer.compare(parentNode, instances1);
}
}@manhvvhtth
How to integrate your code into my own project?
I am comparing two objects which has String arrays like this
working.foo[0].bar
working and foo is object and bar is String array
To @songtianyi ,
First, you need to add addition differ like below:
public ObjectDiffer createObjectDifferHelper() {
final ObjectDifferBuilder objectDifferBuilder = ObjectDifferBuilder.startBuilding();
ObjectDiffer objectDiffer = objectDifferBuilder
.differs().register((differDispatcher, nodeQueryService) -> new ByteArrayDiffer())
.differs().register((differDispatcher, nodeQueryService) -> new ArrayDiffer(differDispatcher, objectDifferBuilder))
.build();
return objectDiffer;
}
// herin I also created ByteArrayDiffer
import de.danielbechler.diff.access.Instances;
import de.danielbechler.diff.differ.Differ;
import de.danielbechler.diff.node.DiffNode;
public final class ByteArrayDiffer implements Differ {
@Override
public boolean accepts(Class<?> aClass) {
return byte[].class.equals(aClass);
}
@Override
public DiffNode compare(DiffNode diffNode, Instances instances) {
final DiffNode beanNode = new DiffNode(diffNode, instances.getSourceAccessor(), instances.getType());
if (instances.areNull() || instances.areSame())
beanNode.setState(DiffNode.State.UNTOUCHED);
else if (instances.hasBeenAdded())
beanNode.setState(DiffNode.State.ADDED);
else if (instances.hasBeenRemoved())
beanNode.setState(DiffNode.State.REMOVED);
else
beanNode.setState(DiffNode.State.CHANGED);
return beanNode;
}
}
Then you can use your object differ normally:
final ObjectDiffer objectDiffer = createObjectDifferHelper();
DiffNode diffNode = objectDiffer.compare(newRevisionEntity, oldRevisionEntity);
Hope this response is not late :),
To @songtianyi ,
First, you need to add addition differ like below:
public ObjectDiffer createObjectDifferHelper() { final ObjectDifferBuilder objectDifferBuilder = ObjectDifferBuilder.startBuilding(); ObjectDiffer objectDiffer = objectDifferBuilder .differs().register((differDispatcher, nodeQueryService) -> new ByteArrayDiffer()) .differs().register((differDispatcher, nodeQueryService) -> new ArrayDiffer(differDispatcher, objectDifferBuilder)) .build(); return objectDiffer; } // herin I also created ByteArrayDiffer import de.danielbechler.diff.access.Instances; import de.danielbechler.diff.differ.Differ; import de.danielbechler.diff.node.DiffNode; public final class ByteArrayDiffer implements Differ { @Override public boolean accepts(Class<?> aClass) { return byte[].class.equals(aClass); } @Override public DiffNode compare(DiffNode diffNode, Instances instances) { final DiffNode beanNode = new DiffNode(diffNode, instances.getSourceAccessor(), instances.getType()); if (instances.areNull() || instances.areSame()) beanNode.setState(DiffNode.State.UNTOUCHED); else if (instances.hasBeenAdded()) beanNode.setState(DiffNode.State.ADDED); else if (instances.hasBeenRemoved()) beanNode.setState(DiffNode.State.REMOVED); else beanNode.setState(DiffNode.State.CHANGED); return beanNode; } }Then you can use your object differ normally:
final ObjectDiffer objectDiffer = createObjectDifferHelper(); DiffNode diffNode = objectDiffer.compare(newRevisionEntity, oldRevisionEntity);Hope this response is not late :),
I used the method you provided but still reported an error:
java.lang.IllegalArgumentException: class [Ljava.lang.String;