Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scalac bug when calculating the LUB of akka.http.scaladsl.model.MediaTypes fields #9621

Closed
scabug opened this issue Jan 12, 2016 · 8 comments

Comments

@scabug
Copy link

scabug commented Jan 12, 2016

The members of akka.http.scaladsl.model.MediaTypes have different types. Some are of type MediaType.WithOpenCharset while others are of type MediaType.WithFixedCharset. Using them in isolation works fine, but when scalac is asked to calculate the LUB of both types, it blows up in the most peculiar way. This can be worked around by declaring the type explicitly.

Welcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_45).
Type in expressions to have them evaluated.
Type :help for more information.

scala> import akka.http.scaladsl.model.{MediaType, MediaTypes}
import akka.http.scaladsl.model.{MediaType, MediaTypes}

scala> val a = MediaTypes.`application/xml`
a: akka.http.scaladsl.model.MediaType.WithOpenCharset = application/xml

scala> val b = MediaTypes.`application/json`
b: akka.http.scaladsl.model.MediaType.WithFixedCharset = application/json

scala> val boom = Seq(a, b)
error: missing or invalid dependency detected while loading class file 'MediaType.class'.
Could not access type WithFixedCharset in trait akka.http.javadsl.model.MediaType,
because it (or its dependencies) are missing. Check your build definition for
missing or conflicting dependencies. (Re-run with `-Ylog-classpath` to see the problematic classpath.)
A full rebuild may help if 'MediaType.class' was compiled against an incompatible version of akka.http.javadsl.model.MediaType.

scala> val works = Seq[MediaType](a, b)
works: Seq[akka.http.scaladsl.model.MediaType] = List(application/xml, application/json)

Here is a repo with a tiny reproducer https://github.com/rklaehn/invaliddependency

It is probably of interest that ContentType.WithFixedCharset and ContentType.WithOpenCharset are inner interfaces declared in a java class
https://github.com/akka/akka/blob/84fd5a9b2a4ebc1dcfe1cda8c072023ba84b44a0/akka-http-core/src/main/java/akka/http/javadsl/model/MediaType.java

@scabug
Copy link
Author

scabug commented Jan 12, 2016

Imported From: https://issues.scala-lang.org/browse/SI-9621?orig=1
Reporter: @rklaehn
Affected Versions: 2.10.5, 2.11.7
See #1409, #9938

@scabug
Copy link
Author

scabug commented Jan 12, 2016

Konrad Malawski (konrad.malawski) said:
@rudiger: Whoops, did not intend to remove the last added line (just wanted to reformat). I've put it back again.

This would be interesting to get a rough estimate if it's a big problem to fix or we should look into working around it, thanks in advance!

@scabug
Copy link
Author

scabug commented Jan 12, 2016

@adriaanm said:
Using the file from the invaliddependency repo on scala 2.11.x master with debug flags:

[log typer] infer method inst scala.this.Predef.Map.apply[A, B], tparams = List(type A, type B), args = List(scala.this.Tuple2[lang.this.String,model.this.MediaType.WithOpenCharset], scala.this.Tuple2[lang.this.String,model.this.MediaType.WithFixedCharset]), pt = ?, lobounds = List(scala.this.Nothing, scala.this.Nothing), parambounds = List(, )
|    |    |    solving for (A: ?A, B: ?B)
[log typer] ?A setInst lang.this.String
[log typer(->parser ->parser)] [class] >> akka.http.scaladsl.model.MediaRange
[log typer(->parser ->parser ->parser)] [class] >> akka.http.scaladsl.model.MediaRanges
[log typer(->parser ->parser ->parser)] [class] << akka.http.scaladsl.model.MediaRanges
[log typer(->parser ->parser)] ClassfileLoader setting MediaRanges.associatedFile = /Users/adriaan/.ivy2/cache/com.typesafe.akka/akka-http-core-experimental_2.11/jars/akka-http-core-experimental_2.11-2.0.1.jar(akka/http/scaladsl/model/MediaRanges.class)
[log typer(->parser ->parser)] [class] << akka.http.scaladsl.model.MediaRange
[log typer(->parser)] ClassfileLoader setting MediaRange.associatedFile = /Users/adriaan/.ivy2/cache/com.typesafe.akka/akka-http-core-experimental_2.11/jars/akka-http-core-experimental_2.11-2.0.1.jar(akka/http/scaladsl/model/MediaRange.class)
[log typer] missingHook(trait MediaType, Binary): <none>
warning: !!! creating stub symbol to defer error: missing or invalid dependency detected while loading class file 'MediaType.class'.
Could not access type Binary in trait akka.http.javadsl.model.MediaType,
because it (or its dependencies) are missing. Check your build definition for
missing or conflicting dependencies. (Re-run with `-Ylog-classpath` to see the problematic classpath.)
A full rebuild may help if 'MediaType.class' was compiled against an incompatible version of akka.http.javadsl.model.MediaType.
[log typer(->parser ->parser)] [class] >> akka.http.javadsl.model.MediaRange
[log typer(->parser ->parser)] new existential: util.this.Map[lang.this.String,lang.this.String]
[log typer(->parser)] ClassfileLoader setting MediaRange.associatedFile = /Users/adriaan/.ivy2/cache/com.typesafe.akka/akka-http-core-experimental_2.11/jars/akka-http-core-experimental_2.11-2.0.1.jar(akka/http/javadsl/model/MediaRange.class)
[log typer] specializesSymHi: akka.http.scaladsl.model.<refinement>.type . method toRange : (<param> qValue: scala.this.Float)model.this.MediaRange
[log typer] specializesSymLo: akka.http.scaladsl.model.<refinement>.type . method toRange : ()model.this.MediaRange
[log typer] specializesSymHi: akka.http.scaladsl.model.<refinement>.type . method withQValue : (<param> qValue: scala.this.Float)model.this.MediaRange
[log typer] specializesSymLo: akka.http.scaladsl.model.<refinement>.type . method withQValue : (<param> qValue: scala.this.Double)model.this.MediaRange
[log typer] missingHook(trait MediaType, WithFixedCharset): <none>
warning: !!! creating stub symbol to defer error: missing or invalid dependency detected while loading class file 'MediaType.class'.
Could not access type WithFixedCharset in trait akka.http.javadsl.model.MediaType,
because it (or its dependencies) are missing. Check your build definition for
missing or conflicting dependencies. (Re-run with `-Ylog-classpath` to see the problematic classpath.)
A full rebuild may help if 'MediaType.class' was compiled against an incompatible version of akka.http.javadsl.model.MediaType.
[log typer] specializesSymHi: akka.http.scaladsl.model.<refinement>.type . method withParams : (<param> params: Map[String,String])<refinement>.this.WithFixedCharset with model.this.MediaType{}
[log typer] specializesSymLo: akka.http.scaladsl.model.<refinement>.type . method withParams : (<param> params: Map[String,String])model.this.MediaType
error: missing or invalid dependency detected while loading class file 'MediaType.class'.
Could not access type WithFixedCharset in trait akka.http.javadsl.model.MediaType,
because it (or its dependencies) are missing. Check your build definition for
missing or conflicting dependencies. (Re-run with `-Ylog-classpath` to see the problematic classpath.)
A full rebuild may help if 'MediaType.class' was compiled against an incompatible version of akka.http.javadsl.model.MediaType.
java.lang.Throwable
	at scala.reflect.internal.Symbols$StubSymbol$class.fail(Symbols.scala:3469)
	at scala.reflect.internal.Symbols$StubSymbol$class.info(Symbols.scala:3480)
	at scala.reflect.internal.Symbols$StubClassSymbol.info(Symbols.scala:3484)
	at scala.reflect.internal.Symbols$StubClassSymbol.info(Symbols.scala:3484)
	at scala.reflect.internal.Symbols$Symbol.baseTypeSeqLength$1(Symbols.scala:1861)
	at scala.reflect.internal.Symbols$Symbol.isLess(Symbols.scala:1864)
	at scala.reflect.internal.Types$Type.baseTypeIndex(Types.scala:898)
	at scala.reflect.internal.Types$CompoundType.baseType(Types.scala:1401)
	at scala.reflect.internal.Types$ClassTypeRef$class.baseType(Types.scala:1968)
	at scala.reflect.internal.Types$ClassNoArgsTypeRef.baseType(Types.scala:2331)
	at scala.reflect.internal.tpe.TypeComparers$class.firstTry$1(TypeComparers.scala:405)
	at scala.reflect.internal.tpe.TypeComparers$class.isSubType2(TypeComparers.scala:552)
	at scala.reflect.internal.tpe.TypeComparers$class.isSubType1(TypeComparers.scala:320)
	at scala.reflect.internal.tpe.TypeComparers$class.isSubType(TypeComparers.scala:278)
	at scala.reflect.internal.SymbolTable.isSubType(SymbolTable.scala:16)
	at scala.reflect.internal.tpe.TypeComparers$$anonfun$thirdTry$1$1.apply(TypeComparers.scala:480)
	at scala.reflect.internal.tpe.TypeComparers$$anonfun$thirdTry$1$1.apply(TypeComparers.scala:480)
	at scala.collection.LinearSeqOptimized$class.forall(LinearSeqOptimized.scala:83)
	at scala.collection.immutable.List.forall(List.scala:84)
	at scala.reflect.internal.tpe.TypeComparers$class.thirdTry$1(TypeComparers.scala:480)
	at scala.reflect.internal.tpe.TypeComparers$class.secondTry$1(TypeComparers.scala:450)
	at scala.reflect.internal.tpe.TypeComparers$class.firstTry$1(TypeComparers.scala:426)
	at scala.reflect.internal.tpe.TypeComparers$class.isSubType2(TypeComparers.scala:552)
	at scala.reflect.internal.tpe.TypeComparers$class.isSubType1(TypeComparers.scala:320)
	at scala.reflect.internal.tpe.TypeComparers$class.isSubType(TypeComparers.scala:278)
	at scala.reflect.internal.SymbolTable.isSubType(SymbolTable.scala:16)
	at scala.reflect.internal.tpe.TypeComparers$class.thirdTry$1(TypeComparers.scala:492)
	at scala.reflect.internal.tpe.TypeComparers$class.secondTry$1(TypeComparers.scala:450)
	at scala.reflect.internal.tpe.TypeComparers$class.firstTry$1(TypeComparers.scala:426)
	at scala.reflect.internal.tpe.TypeComparers$class.isSubType2(TypeComparers.scala:552)
	at scala.reflect.internal.tpe.TypeComparers$class.isSubType1(TypeComparers.scala:320)
	at scala.reflect.internal.tpe.TypeComparers$class.isSubType(TypeComparers.scala:278)
	at scala.reflect.internal.SymbolTable.isSubType(SymbolTable.scala:16)
	at scala.reflect.internal.Types$class.specializesSym(Types.scala:4172)
	at scala.reflect.internal.SymbolTable.specializesSym(SymbolTable.scala:16)
	at scala.reflect.internal.tpe.GlbLubs$$anonfun$refines$1$1.apply(GlbLubs.scala:376)
	at scala.reflect.internal.tpe.GlbLubs$$anonfun$refines$1$1.apply(GlbLubs.scala:373)
	at scala.collection.LinearSeqOptimized$class.forall(LinearSeqOptimized.scala:83)
	at scala.collection.immutable.List.forall(List.scala:84)
	at scala.reflect.internal.tpe.GlbLubs$class.refines$1(GlbLubs.scala:373)
	at scala.reflect.internal.tpe.GlbLubs$$anonfun$excludeFromLub$1$1.apply(GlbLubs.scala:345)
	at scala.reflect.internal.tpe.GlbLubs$$anonfun$excludeFromLub$1$1.apply(GlbLubs.scala:345)
	at scala.collection.LinearSeqOptimized$class.exists(LinearSeqOptimized.scala:93)
	at scala.collection.immutable.List.exists(List.scala:84)
	at scala.reflect.internal.tpe.GlbLubs$class.excludeFromLub$1(GlbLubs.scala:345)
	at scala.reflect.internal.tpe.GlbLubs$$anonfun$25.apply(GlbLubs.scala:380)
	at scala.reflect.internal.tpe.GlbLubs$$anonfun$25.apply(GlbLubs.scala:380)
	at scala.collection.TraversableLike$WithFilter$$anonfun$foreach$1.apply(TraversableLike.scala:744)
	at scala.collection.immutable.List.foreach(List.scala:381)
	at scala.reflect.internal.Scopes$Scope.foreach(Scopes.scala:373)
	at scala.collection.TraversableLike$WithFilter.foreach(TraversableLike.scala:743)
	at scala.reflect.internal.tpe.GlbLubs$class.lub1$1(GlbLubs.scala:380)
	at scala.reflect.internal.tpe.GlbLubs$class.lub0$1(GlbLubs.scala:322)
	at scala.reflect.internal.tpe.GlbLubs$class.lub(GlbLubs.scala:419)
	at scala.reflect.internal.SymbolTable.lub(SymbolTable.scala:16)
	at scala.reflect.internal.tpe.TypeConstraints$class.solveOne$1(TypeConstraints.scala:249)
	at scala.reflect.internal.tpe.TypeConstraints$$anonfun$solve$1.apply(TypeConstraints.scala:260)
	at scala.reflect.internal.tpe.TypeConstraints$$anonfun$solve$1.apply(TypeConstraints.scala:260)
	at scala.reflect.internal.util.Collections$class.foreach3(Collections.scala:231)
	at scala.reflect.internal.SymbolTable.foreach3(SymbolTable.scala:16)
	at scala.reflect.internal.tpe.TypeConstraints$class.solve(TypeConstraints.scala:260)
	at scala.reflect.internal.SymbolTable.solve(SymbolTable.scala:16)
	at scala.tools.nsc.typechecker.Infer$class.solvedTypes(Infer.scala:145)
	at scala.tools.nsc.Global$$anon$1.solvedTypes(Global.scala:462)
	at scala.tools.nsc.typechecker.Infer$Inferencer.methTypeArgs(Infer.scala:550)

@scabug
Copy link
Author

scabug commented Jan 12, 2016

@adriaanm said:
Looks like this is #1409 -- the nested java interface is not seen on separate compilation

@scabug
Copy link
Author

scabug commented Jan 12, 2016

Konrad Malawski (konrad.malawski) said:
That makes me realise we should be able to get away from the nested interface rather easily. I'll give it a shot on our end to not be dependent on having this fixed.

@scabug
Copy link
Author

scabug commented Jan 13, 2016

@rklaehn said:
@adriaanm does this also happen if you use nested traits instead of nested interfaces? In that case it would not be just a java interop bug.

@scabug
Copy link
Author

scabug commented Jan 16, 2016

Konrad Malawski (konrad.malawski) said:
Good news everyone (somewhat at least), moving the inner interfaces to be defined in Scala resolves the problem, so it's only related to Java inter-op.

If you want a reproducer Rudiger's link works well, and you can update the Akka version there to 2.0.2 to see that "oh now it works" in case that helps debugging.
Here's the patch that solves it on our end: https://github.com/akka/akka/pull/19460/files

@SethTisue
Copy link
Member

sounds like this was just a duplicate of #1409? though then I'm not sure why it wasn't closed earlier. in any case, it's been a while so I think we should presume this is closeable as a duplicate unless someone wants to say otherwise.

@SethTisue SethTisue closed this as not planned Won't fix, can't repro, duplicate, stale Apr 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants