bug
bug copied to clipboard
`MalformedParameterizedTypeException` errors with Scala 2.12 parallel library
reproduction steps
using Scala 2.12.15,
This bug can be reproduced in Java 8, 11, 17. Here is a small example to reproduce the bug:
C.java
class C {
public static void main(String[] a) throws Exception {
Class c = scala.collection.parallel.ParIterableLike.Accessor.class;
java.lang.reflect.Method m[] = c.getMethods();
java.lang.reflect.Method init = null;
for(int i = 0; i < m.length; i++) {
if (m[i].toString().contains("$init$")) {
init = m[i];
break;
}
}
init.getGenericParameterTypes();
}
}
Execute
javac -cp $SOME_DIR/scala-library-2.12.15.jar C.java
java -cp $SOME_DIR/scala-library-2.12.15.jar:. C
problem
I encountered some issues when calling getGenericParameterTypes on some classes in the 2.12 parallel library:
[sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.validateConstructorArguments(ParameterizedTypeImpl.java:58),
sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.<init>(ParameterizedTypeImpl.java:51),
sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.make(ParameterizedTypeImpl.java:92),
sun.reflect.generics.factory.CoreReflectionFactory.makeParameterizedType(CoreReflectionFactory.java:105),
sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:151),
sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49),
sun.reflect.generics.repository.ConstructorRepository.getParameterTypes(ConstructorRepository.java:94),
java.lang.reflect.Executable.getGenericParameterTypes(Executable.java:283),
java.lang.reflect.Method.getGenericParameterTypes(Method.java:283)]
I believe this is an issue with some of the jar files generated by the 2.12 Scala compiler. Although the parallel library is removed in version 2.13, the bug may still exist for other classes. We have not seen any indication of this bug getting reported or fixed in existing issues.
vanilla REPL
scala> $intp.classLoader.loadClass("scala.collection.parallel.ParIterableLike$Accessor").getMethods.filter(_.getName == "$init$").head.getGenericParameterTypes
java.lang.reflect.MalformedParameterizedTypeException
at java.base/sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.validateConstructorArguments(ParameterizedTypeImpl.java:59)
at java.base/sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.<init>(ParameterizedTypeImpl.java:52)
at java.base/sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.make(ParameterizedTypeImpl.java:93)
at java.base/sun.reflect.generics.factory.CoreReflectionFactory.makeParameterizedType(CoreReflectionFactory.java:105)
at java.base/sun.reflect.generics.visitor.Reifier.visitClassTypeSignature(Reifier.java:151)
at java.base/sun.reflect.generics.tree.ClassTypeSignature.accept(ClassTypeSignature.java:49)
at java.base/sun.reflect.generics.repository.ConstructorRepository.computeParameterTypes(ConstructorRepository.java:111)
at java.base/sun.reflect.generics.repository.ConstructorRepository.getParameterTypes(ConstructorRepository.java:87)
at java.base/java.lang.reflect.Executable.getGenericParameterTypes(Executable.java:279)
at java.base/java.lang.reflect.Method.getGenericParameterTypes(Method.java:330)
... 28 elided
2.13 hides more stack
scala> $intp.classLoader.loadClass("scala.collection.parallel.ParIterableLike$Accessor").getMethods.filter(_.getName == "$init$").head.getGenericParameterTypes
java.lang.reflect.MalformedParameterizedTypeException
at java.base/sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl.validateConstructorArguments(ParameterizedTypeImpl.java:59)
... 41 elided
Maybe in the area of https://github.com/scala/scala/pull/8055
The most valuable next step here would be to have a standalone reproducer on 2.13 that doesn't involve an external library (since scala-parallel-collections is now an external library).
After searching all methods in the scala-library-2.13.7.jar we did not find any methods that reproduce the issue. However, in scala-parallel-collections_2.13-1.0.4.jar we found that the following methods reproduce the issue:
scala.collection.parallel.ParIterableLike$StrictSplitterCheckTask$init$
scala.collection.parallel.ParIterableLike$NonDivisibleTask$init$
scala.collection.parallel.ParIterableLike$Accessor$init$
scala.collection.parallel.ParIterableLike$BuilderOps$init$
Thanks for narrowing it down
// access flags 0x9
// signature (Lscala/collection/parallel/ParIterableLike<TT;TCC;TRepr;TSequential;>.StrictSplitterCheckTask;)V
// declaration: void $init$(scala.collection.parallel.ParIterableLike<T, CC, Repr, Sequential>.StrictSplitterCheckTask)
public static $init$(Lscala/collection/parallel/ParIterableLike$StrictSplitterCheckTask;)V
Will have to spend more time later to figure out where the issue is.