augustjune / context-applied

Compiler plugin for intuitive tagless final
MIT License
128 stars 8 forks source link

java.lang.ClassFormatError when using auxiliary constructor. #6

Closed kczulko closed 4 years ago

kczulko commented 4 years ago

Hi,

First of all: Thank you for your work! My codebase contains some shapeless goodies. Unfortunately following code throws in runtime (sorry but I didn't manage to prepare sample project...):

abstract class SomeClass[A <: String](implicit w: Witness.Aux[A]) {
  type B
  def aName: String = w.value
}

That what sbt says:

[info] blahblahbah.MainTest *** ABORTED ***
[info]   java.lang.ClassFormatError: Illegal class name "<somename>$Witness.Aux$SomeClass$" in class file <somename>/SomeClass
[info]   at java.lang.ClassLoader.defineClass1(Native Method)
[info]   at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
[info]   at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
[info]   at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
[info]   at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
[info]   at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
[info]   at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
[info]   at java.security.AccessController.doPrivileged(Native Method)
[info]   at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
[info]   at java.lang.ClassLoader.loadClass(ClassLoader.java:424)

and that what bazel says:

*** RUN ABORTED *** (1 second, 955 milliseconds)
  java.lang.ClassFormatError: Class name contains illegal character '.' in descriptor in class file <somename>/SomeClass
  at java.lang.ClassLoader.defineClass1(Native Method)
  at java.lang.ClassLoader.defineClass(ClassLoader.java:763)
  at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
  at java.net.URLClassLoader.defineClass(URLClassLoader.java:468)
  at java.net.URLClassLoader.access$100(URLClassLoader.java:74)
  at java.net.URLClassLoader$1.run(URLClassLoader.java:369)
  at java.net.URLClassLoader$1.run(URLClassLoader.java:363)
  at java.security.AccessController.doPrivileged(Native Method)
  at java.net.URLClassLoader.findClass(URLClassLoader.java:362)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
  at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
  at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
  ...

When I remove context-applied from both sbt and bazel build definition, my code runs smoothly. Maybe it seems that . between Witness and Aux causes the problem?

My env:

Even though it might be hard for me right now, if I could somehow help with this issue please let me know.

Best regards, Karol

augustjune commented 4 years ago

Hi @kczulko Thanks for the detailed report here! Great job 👍 I will take a closer look at this later and let you know what I see.

augustjune commented 4 years ago

Hi @kczulko! Sorry for such a long delay.

From the error message, it's pretty clear that the problem hides in . character, but I couldn't reproduce the issue. Tried this piece of code and it actually compiles:

import shapeless.Witness

abstract class SomeClass[A <: String](implicit w: Witness.Aux[A]) {
  type B
  def aName: String = w.value
}

I've added a test case that covers this conjecture #7 and it was built successfully by travis. I'm curious why that doesn't work in your case, maybe there's some additional settings/code that changes makes plugin behave differently.

I'd really like to get to the bottom of this, so any additional info from you will help. Thanks

kczulko commented 4 years ago

Good evening @augustjune ,

Finally I've found some spare time and reproduced it somehow here:

https://github.com/kczulko/context-applied-defect-6

Please execute sbt run and repeat it once again but this time please comment out addCompilerPlugin("augustjune" ...) from sbt file.

Best regards Karol

augustjune commented 4 years ago

Hey @kczulko, that's just awesome. Didn't try to actually run the example, just assumed the compiling phase is enough.

I'm gonna prepare a quick fix and release it with a new version. Thanks for your contribution to the project 🙏