Is this allowed in Scala code:
DomNode node = node.getFirstChild()
where DomNode is Java type from external java library and getFirstChild() is defined on DomNode type.
I am porting existing java program to scala and it would be very convenient if I leave original java declerations as is to minimize porting efforts.
You can use Java classes in a Scala program, but you would ofcourse have to use Scala syntax:
val node: DomNode = node.getFirstChild()
You cannot use Java syntax in the form Type variableName.
edit (thanks to ericacm) - You can also just specify
val node = node.getFirstChild()
so you don't have to specify the type of node explicitly; you can let Scala infer the type.
IntelliJ IDEA can translate from Java to Scala for you. If you paste Java code into a ".scala" file IntelliJ IDEA notices it and asks you if you would like to try an automatic conversion. You might wanna check it out.
PS
I never tried it out myself...
Related
I have a scala.js project. There I have a strange behavior with Scala.Meta and Binding.scala.
I want to create a case class from a case class:
case class SimpleCaseClass(i: Int, s: String, list: Seq[String])
should generate to:
SimpleCaseClassFormData(Var[Int], Var[String], Vars[String])
as soon that I have a Vars, I get the following error:
A method defined in a JavaScript raw type of a Scala.js library has been called. This is most likely because you tried to run Scala.js binaries on the JVM. Make sure you are using the JVM version of the libraries.
java.lang.Error: A method defined in a JavaScript raw type of a Scala.js library has been called. This is most likely because you tried to run Scala.js binaries on the JVM. Make sure you are using the JVM version of the libraries.
at scala.scalajs.js.package$.native(package.scala:134)
at scala.scalajs.js.Array.push(Array.scala:106)
at scala.scalajs.js.JSConverters$JSRichGenTraversableOnce$.$anonfun$toJSArray$1(JSConverters.scala:60)
Without (for example SimpleCaseClassFormData(Var[Int], Var[String])
) it works.
Here you find the whole project: scala-adapters-form
Macro annotation is deprecated (See https://github.com/scalameta/scalameta/issues/1182)
You can create an sbt plugin based on Scala Meta instead. See https://github.com/ThoughtWorksInc/sbt-example/ as an example to implement such a plugin.
To avoid incompatible versions, you should use the sbt's built-in Scala Meta, which is version 1.7.0.
In my code, I use classTag[JValue] want to get org.json4s.JsonAST.JValue ,
but actually it returns org.json4s.JsonAST$JValue, it is strange ! why there is the $?
I am new guy use scala ,could someone answer me ? thanks a lot
The name you use to refer to a class/method/etc. in your code and the name it has in bytecode produced by the compiler doesn't have to be the same. Scala compiler needs to be more of this name-mangling than the Java compiler, but this specific case is same for both.
The reason is that inner classes don't really exist on JVM: they are normal classes which have an additional field containing the outer instance. The JVM name of the class looks like <outer_class>$<inner_class>.
In Scala and Java, $ in a name generally indicates it's mangled in some way (though it is a legal character for programmers to use as well).
class Wish{
val s = "Hello! User. Wish you a Great day."
}
object Wish{
def main(args: Array[String]){
val w = new Wish()
println("Value - " + w.s )
}
}
Java classes can be used in Scala. Similarly, can Scala classes be used in Java?
Yes, Scala classes can be called from Java and vice versa.
The below text is taken from: Scala FAQs
What does it mean that Scala is compatible with Java?
The standard Scala backend is a Java VM. Scala classes are Java classes, and vice versa. You can call the methods of either language from methods in the other one. You can extend Java classes in Scala, and vice versa. The main limitation is that some Scala features do not have equivalents in Java, for example traits.
The following post also could be helpful to you: how to call Scala from Java
Yes. If you want to do this, there are a few things you might want to remember:
Do not use operators in your method names or provide a wordy alternative. Operator names can be called from Java but are mangled into somethings very ugly.
Java users might expect Java style getters and setters. You can produce those automatically by adding #BeanProperty annotation to fields.
In the same way Java user might be accustomed to factory methods called ClassName.of where Scala uses .apply. Those you have to provide by hand, if you want to provide that service.
I am getting the above mentioned Error from Scala compiler.
I am quite new to Scala and experimenting with it by converting a Java project that I have, to Scala. In my Java project, I am using Apache 'commons-chain' and I have a class that is extending 'org.apache.commons.chain.impl.ContextBase' and I am getting this error for it. I searched the internet it seems this problem has something to do with type erasure but my class doesn't not do anything special, just inherits from this class.
class SpecialContext extends ContextBase {
}
and here is the exact error I get..
Error:(10, 7) illegal inheritance;
class SpecialContext inherits different type instances of trait Map:
java.util.Map[K,V] and java.util.Map[K,V]
class SpecialContext extends ContextBase {
One of the attractions of Scala for me, while I can use nice language features of Scala, I would be still able to use the extensive number of open source libraries of the Java. After this experience, I am questioning this fact, considering my class not doing anything special, is it always this problematic to integrate the Java world and Scala world.
First my question is off-course is there a solution for the problem I described above?
Second question is, how is your experience integrating Scala and Java libraries? Or am I following the wrong way, are there ports of the popular Java libraries to Scala, like command-chain here, or lets say Spring....
Thx for answers.
The problem with ContextChain is that it uses raw types: in https://commons.apache.org/proper/commons-chain/apidocs/org/apache/commons/chain/impl/ContextBase.html you can see Map and HashMap instead of Map<Something, Something>.
Java only supports raw types to integrate with old, pre-generics code (to remind you, Java 5 was released in 2004), so you shouldn't see them in modern Java libraries. Scala doesn't support them at all.
As asked in this thread on the Scala mailing list, how can I create an embedded Scala REPL that inherits the classpath of the parent program? Suppose the parent Scala program is launched using scala -cp <classpath> ...; can <classpath> be accessed as a string and used to initialize the embedded REPL? (The Java classpath, available via System.getProperty("java.class.path"), appears to differ from the Scala classpath.)
Alternatively, perhaps the embedded Scala REPL can inherit or construct its ClassLoader from the parent process (Michael Dürig's ScalaDays 2010 talk might be relevant). Is this the recommended approach?
I'm trying to do the same thing, and I just found a way my out by Googling:
lazy val urls = java.lang.Thread.currentThread.getContextClassLoader match {
case cl: java.net.URLClassLoader => cl.getURLs.toList
case _ => error("classloader is not a URLClassLoader")
}
lazy val classpath = urls map {_.toString}
The above code gets you the classpath in current context.
settings.classpath.value = classpath.distinct.mkString(java.io.File.pathSeparator)
Put that into your settings.classpath and you should be able to fire up dispatch or whatever library you need.
set the usejavacp property to true:
val settings = new scala.tools.nsc.Settings
settings.usejavacp.value = true
There does not seem to be an easy way to access the "Scala classpath" from within a running Scala program (in contrast, the "Java classpath" is available through the java.class.path system property). One would like to access, e.g., the field Calculated.userClasspath in the instance of scala.tools.PathResolver, but the latter does not seem accessible. Perhaps the easiest work-around is to modify the scala launch script to store the -classpath parameter string in an environment variable.
Assuming the desired Scala classpath can be determined, it can be passed to the embedded Scala interpreter via:
settings.classpath.value = ...
Update: although the Scala classpath string may not be directly attainable from the Scala runtime, #Eugene points out that it can be extracted from the context classloader. Thanks.