Task.par() doesn't work with Vavr List, throw ClassCastException
WeishiZeng opened this issue · 4 comments
Class: com.linkedin.parseq.Task
Method:
public static <T> ParTask<T> par(final Iterable<? extends Task<? extends T>> tasks) {
Use case to reproduce:
List<Task<MyObject>> javaList = new ArrayList<>();
javaList.add(t1);
javaList.add(t2);
io.vavr.collection.List<Task<MyObject>> vavrList = io.vavr.collection.List.of(t1,t2);
Task.par(vavrList); //this line will fail at Runtime: "java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Lcom.linkedin.parseq.Task;"
Task.par(javaList); //this works fine
StackTrace:
java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to [Lcom.linkedin.parseq.Task;
at com.linkedin.parseq.ParTaskImpl.tasksFromIterable(ParTaskImpl.java:76)
at com.linkedin.parseq.ParTaskImpl.<init>(ParTaskImpl.java:60)
at com.linkedin.parseq.Task.par(Task.java:1750)
at [method calling Task.par]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.testng.internal.MethodInvocationHelper.invokeMethod(MethodInvocationHelper.java:124)
at org.testng.internal.Invoker.invokeMethod(Invoker.java:583)
at org.testng.internal.Invoker.invokeTestMethod(Invoker.java:719)
at org.testng.internal.Invoker.invokeTestMethods(Invoker.java:989)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:125)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:109)
at org.testng.TestRunner.privateRun(TestRunner.java:648)
at org.testng.TestRunner.run(TestRunner.java:505)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:455)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:450)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:415)
at org.testng.SuiteRunner.run(SuiteRunner.java:364)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:52)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:84)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1208)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1137)
at org.testng.TestNG.runSuites(TestNG.java:1049)
at org.testng.TestNG.run(TestNG.java:1017)
at org.testng.IDEARemoteTestNG.run(IDEARemoteTestNG.java:73)
at org.testng.RemoteTestNGStarter.main(RemoteTestNGStarter.java:123)
The reason this happens is that arrays in java are not covariant.
This is probably an issue with any Iterable
that does not extend Collection
Here an unsafe cast is performed that will always fail since you can't cast an Object[]
to a Task[]
Fix should be create a new Task[]
the same size of the ArrayList then call https://docs.oracle.com/javase/8/docs/api/java/util/List.html#toArray-T:A- with that array.
Can this issue be fixed?
I'll be glad to create a PR for this.
@Anmol-Singh-Jaggi , I think the workaround could be this:
io.vavr.collection.List<Task<MyObject>> vavrList = io.vavr.collection.List.of(t1, t2);
Task.par(vavrList.asJava());
(see https://www.javadoc.io/doc/io.vavr/vavr/0.9.0/io/vavr/collection/List.html#asJava-- )
Yes we have been converting vavr list to java list manually.
But it would be great it parseq could support vavr lists natively to avoid the unnecessary conversion to java list.