aiguy aiguy - 1 month ago 18
Scala Question

Scala visibility when accessed by Java classes

I have a module written in Scala that I need to integrate into a Java web application. Everything works great, except the fact that methods and fields that are

private[somepackage]


in the Scala classes appear to be accessible from the Java code from outside that package. Is there any way to hide those?

EDIT: example illustrating what is happening

package my.scala.module

class SomeClass {
private[scala] val myValue = "this should be hidden"
}


package com.something.service;
import my.scala.module.SomeClass;

public class MyService {
private static SomeClass someInstance = new SomeClass();

public static void main(String[] args){
System.out.println(someInstance.myValue());
}
}


Running main will cause "this should be hidden" to print

Answer

There is no way to encode this constraint in JVM bytecode. It is enforced by the Scala compiler, but neither the JVM nor Java know anything about it.

There are some Scala features which can be encoded in JVM bytecode, and some which can't.

In particular, there are some constraints which cannot be encoded in JVM bytecode, e.g. sealed or private[foo], or val. Which means that if you get your hands on the compiled JVM bytecode of a Scala source file, then you can do stuff that you can't do from Scala by interacting with the code through a language that is not Scala.

This is not specific to the JVM backend, you have similar, and even more pronounced problems with Scala.js, since the compilation target here (ECMAScript) offers even less ways of expressing constraints than JVM bytecode does.

But really, this is just a general problem: I can take a language as safe and pure as Haskell, compile it to native code, and if I get my hands on the compiled binary, all safety will be lost. In fact, most Haskell compilers perform (almost) complete type erasure, so there are literally no types, and no type constraints left after compilation.

Comments