Its a very peculiar case, seems to be a .class file corruption. Our Application depends on a dependency provided by other team. There are 2 java files of relevance: FTGService
and FTGServiceLight implements FTGService
.
So when I do javap -p FTGService
it prints:
....
public abstract java.util.List<munshi.transfers.domain.TransferredFile> getArchivedFilesByLastSyncTime(java.util.Date, java.util.Date, java.util.Date, java.util.Date, java.util.Date, java.util.List<java.lang.String>, java.util.List<java.lang.Integer>);
On doing javap -p FTGServiceLight
, it prints:
....
public java.util.List<munshi.transfers.domain.TransferredFile> getArchivedFilesByLastSyncTime(java.util.Date, java.util.Date, java.util.Date, java.util.Date, java.util.Date, java.util.List<java.lang.String>, java.util.List<java.lang.Integer>);
....
When I do javap -v FTGServiceLight
, the relevant information can be found here.
But on running it throws an error:
java.lang.AbstractMethodError: munshi.transfers.service.light.FTGServiceLight.getArchivedFilesByLastSyncTime(Ljava/util/Date;Ljava/util/Date;Ljava/util/Date;Ljava/util/Date;Ljava/util/Date;Ljava/util/List;Ljava/util/List;)Ljava/util/List; at broker.services.resolver.impl.FileSyncServiceImpl.fetchFiles(FileSyncServiceImpl.java:71) at broker.services.resolver.impl.TransferFileSync.run(TransferFileSync.java:71) at sun.reflect.GeneratedMethodAccessor129.invoke(Unknown Source) at
getArchivedFilesByLastSyncTime
is being marked as abstract
for some reason. Further when I debug it, this is what it shows as on doing:
FTGServiceLight.getMethod("getArchivedFilesByLastSyncTime",Date.class,Date.class,Date.class,Date.class,Date.class, List.class, List.class))
Note modifiers
is shown as 1025
and doing Modifiers.isAbstract(1025)
returns true
. So the method getArchivedFilesByLastSyncTime
on debugging is shown as abstract
but javap
suggests it other wise. But when I decompile FTGServiceLight
, it indeed shows the method body, so it seems like it is overridden.
What might be causing this behavior
PS: I have checked mvn dependency tree, and an alternative version for this class never comes in picture.
It looks like a multiple dependencies issue indeed. Just inspecting Maven dependency tree doesn't ensure that you don't have multiple versions of the same class at runtime.
It can be cached, it can be loaded from a different place, etc. In the FileSyncServiceImpl, try printing out the location from where the FTGServiceLight was loaded:
System.out.println(
FTGServiceLight.class.getClassLoader().getResource(
FTGServiceLight.class.getName().replace('.', '/') + ".class"));
And compare to the context where this class is used:
System.out.println(
FileSyncServiceImpl.class.getClassLoader().getResource(
FileSyncServiceImpl.class.getName().replace('.', '/') + ".class"));
Is it the same classlaoder?
One more thing you can try is to inspect what are the locations that the classloader is using to load the classes from. In FileSyncServiceImpl do:
System.out.print(
Arrays.toString(((URLClassLoader)
Test1.class.getClassLoader()).getURLs()));
It will give you the list of jar files (and directories) that are located by this classloader. You can then check if FTGServiceLight is located in any of those and if it is present multiple times.