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

published 0.1.0 JARs don't work #15

Closed
SethTisue opened this issue Mar 20, 2017 · 7 comments · Fixed by #17
Closed

published 0.1.0 JARs don't work #15

SethTisue opened this issue Mar 20, 2017 · 7 comments · Fixed by #17

Comments

@SethTisue
Copy link
Member

resolvers += "nightlies" at "https://scala-ci.typesafe.com/artifactory/scala-integrate/"
scalaVersion := "2.13.0-pre-e2a2cba"
libraryDependencies += "org.scala-lang.modules" %% "scala-parallel-collections" % "0.1.0"
Welcome to Scala 2.13.0-pre-e2a2cba (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_112).
Type in expressions for evaluation. Or try :help.

scala> import scala.collection.parallel.CollectionConverters._
import scala.collection.parallel.CollectionConverters._
error: missing or invalid dependency detected while loading class file 'CollectionConverters.class'.
Could not access type CustomParallelizable in package scala.collection,
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 'CollectionConverters.class' was compiled against an incompatible version of scala.collection.
@SethTisue
Copy link
Member Author

@szeiger is it obvious to you what's going on here?

@SethTisue
Copy link
Member Author

the published JAR only includes the contents of the scala.collection.parallel package, omitting classes like CustomParallelizable which are in scala.collection (not to mention the stuff in scala.collection.generic)

@SethTisue
Copy link
Member Author

@szeiger is it because OsgiKeys.exportPackage := Seq(s"scala.collection.parallel.*;version=${version.value}"),?

related: #5

can I ask you to sort this out? I can take care of publishing 0.1.1 once some solution is in place, even if it's an interim solution

SethTisue pushed a commit to SethTisue/scala-parallel-collections that referenced this issue Mar 20, 2017
Top level modules in Scala currently desugar as:

```
class C; object O extends C { toString }
```

```
public final class O$ extends C {
  public static final O$ MODULE$;

  public static {};
    Code:
       0: new           scala#2                  // class O$
       3: invokespecial scala#12                 // Method "<init>":()V
       6: return

  private O$();
    Code:
       0: aload_0
       1: invokespecial scala#13                 // Method C."<init>":()V
       4: aload_0
       5: putstatic     scala#15                 // Field MODULE$:LO$;
       8: aload_0
       9: invokevirtual scala#21                 // Method java/lang/Object.toString:()Ljava/lang/String;
      12: pop
      13: return
}
```

The static initalizer `<clinit>` calls the constructor `<init>`, which
invokes superclass constructor, assigns `MODULE$= this`, and then runs
the remainder of the object's constructor (`toString` in the example
above.)

It turns out that this relies on a bug in the JVM's verifier: assignment to a
static final must occur lexically within the <clinit>, not from within `<init>`
(even if the latter is happens to be called by the former).

I'd like to move the assignment to <clinit> but that would
change behaviour of "benign" cyclic references between modules.

Example:

```
package p1; class CC { def foo = O.bar}; object O {new CC().foo; def bar = println(1)};

// Exiting paste mode, now interpreting.

scala> p1.O
1
```

This relies on the way that we assign MODULE$ field after the super class constructors
are finished, but before the rest of the module constructor is called.

Instead, this commit removes the ACC_FINAL bit from the field. It actually wasn't
behaving as final at all, precisely the issue that the stricter verifier
now alerts us to.

```
scala> :paste -raw
// Entering paste mode (ctrl-D to finish)

package p1; object O

// Exiting paste mode, now interpreting.

scala> val O1 = p1.O
O1: p1.O.type = p1.O$@ee7d9f1

scala> scala.reflect.ensureAccessible(p1.O.getClass.getDeclaredConstructor()).newInstance()
res0: p1.O.type = p1.O$@64cee07

scala> O1 eq p1.O
res1: Boolean = false
```

We will still achieve safe publication of the assignment to other threads
by virtue of the fact that `<clinit>` is executed within the scope of
an initlization lock, as specified by:

  https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-5.html#jvms-5.5

Fixes scala/scala-dev#SD-194
@szeiger
Copy link
Contributor

szeiger commented Mar 21, 2017

Yes, the direct cause is the missing export. I'll fix that. In the long run we need to avoid the split package. It can be used with OSGi but not with Java 9 modules.

@SethTisue
Copy link
Member Author

SethTisue commented Mar 21, 2017

@SethTisue
Copy link
Member Author

@SethTisue
Copy link
Member Author

Your build exited with 0. 🍺

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants