My first contact with Scala was through the SimplyScala tutorial: You don't need to install anything and can just start to code. After some hours I fell in love with the language...
Years later, I have written a web documentation for a Scala library as a Play Application. It would be cool to build something like SimplyScala and integrate it in the documentation, so that the user can enter Scala commands in the browser and get the result back.
SimplyScala works like LotREPLS (old Open-Source-Java-Project with just few LOCs) on the Google App Engine.
Is is also possible to create something like this on my own server without getting security holes (f.ex. the user should not read files from the server...)?
I just need the "base" of the Scala language without any imports just like in SimplyScala.
My first idea is to write an own SecurityManager and handle time-outs so that the user cannot consume too much server time. Is there any easier way or an existing open-source project?
Or is it just more rational to advice the user to install Scala and work with the terminal instead of the browser? ;-)
On the Scala homepage is a similar Play-project idea for the Summer of Code 2012 Scala Projects: but I cannot find any results.
Probably the most secure so far is http://www.scala-js-fiddle.com/ (code on GitHub) simply because it does not even run the code on the server, but on the client!
The gotcha is: it's not truly Scala code, it is Scala.js, which is a dialect of Scala, is still experimental, etc. But it might be enough for your use case.
Answering my own question:
Scala Consoles, that don't care about security (?):
Scala Web Console
Scala IDE
Tryscala
One web interface which handles somehow security:
The impressive Scalakata project, Source is on GitHub.
It's a Lift project that defines an own security manager (see src/main/scala/com.github.masseguillaume/security) and handle time-outs (see src/main/scala/com.github.masseguillaume/service/KateEval.scala). Now I have to think, if that is secure enough...
https://codebrew.io/ seems to work quite well as Scala REPL
code available at https://github.com/CodeBrew-io
with: libraryDependencies += "org.scala-lang" % "scala-compiler" % scalaVersion.value
Compiler (scala.tools.nsc.Global)
This is the most accurate method to evaluate scala code.
compileSources will add a new class in the classloader
usage
Repl
IMain
usage
JSR-223
import javax.script.ScriptEngineManager
val e = new ScriptEngineManager().getEngineByName("scala")
e.put("n", 10)
e.eval("1 + n") // 11
Reflection Toolbox
import scala.reflect.runtime.{currentMirror => cm}
import scala.reflect.runtime.universe._
import scala.tools.reflect.ToolBox
val tb = cm.mkToolBox()
tb.eval(tb.parse("1+1"))
// res0: Any = 2
Presentation (interactive) compiler (scala.tools.nsc.interactive.Global)
This is for autocompletion and other interactive features.
doc
usage
Related
I'm new to Scala/SBT and I'm having trouble understanding how to just try out the classes and functions of a package to see what they're about, to get a feel for them. For example, take https://github.com/plokhotnyuk/rtree2d . What I want to do is something like (in the top level folder of the project)
# sbt
> console
> import com.github.plokhotnyuk.rtree2d.core._
...
etc. But this won't work as it can't find the import even though this is in the project. I apologize for the vague question, though I hope from my hand-waving it's clear what I want to do. Another way to put it maybe, is that I'm looking for something like the intuitive ease of use which I've come to take for granted in Python -- using just bash and the interpreter. As a last resort I can create a separate project and import this package and write a Main object but this seems much too roundabout and cumbersome for what I want to do. I'd also like if possible to avoid IDEs, since I never really feel in control with them as they do all sorts of things behind the scenes in the background adding a lot of bulk and complexity.
rtree2d takes advantage of sbt's multi-module capabilities; a common use for this is to put the core functionality in a module and have less core aspects (e.g. higher-level APIs or integrations with other projects) in modules which depend on the core: all of these modules can be published independently and have their own dependencies.
This can be seen in the build.sbt file:
// The main project -- LR
lazy val rtree2d = project.in(file("."))
.aggregate(`rtree2d-coreJVM`, `rtree2d-coreJS`, `rtree2d-benchmark`)
// details omitted --LR
// Defines the basic skeleton for the core JVM and JS projects --LR
lazy val `rtree2d-core` = crossProject(JVMPlatform, JSPlatform)
// details omitted
// Turns the skeleton into the core JVM project --LR
lazy val `rtree2d-coreJVM` = `rtree2d-core`.jvm
// Turns the skeleton into the core JS project --LR
lazy val `rtree2d-coreJS` = `rtree2d-core`.js
lazy val `rtree2d-benchmark` = project
In sbt, commands can be scoped to particular modules with module/command, so in the interactive sbt shell (from the top-level), you can do
> rtree2d-coreJVM/console
to run the console within the JVM core module. You could also run sbt 'rtree2d-coreJVM/console' directly from the shell in the top level, though this may require some care around shell quoting etc.
Spent a few hours trying to figure out how to do this. Over the course of it I have looked at a few seemingly promising questions but none of them seem to quite fit what I'm doing.
I've got three library jars, let's call them M, S, and H. Library M has things like:
case class MyModel(x: Int, s: String)
and then library S uses the play-json library, version 2.3.8, to provide implicit serializers for the classes defined by M
trait MyModelSerializer {
implicit val myModelFormt = Json.format[MyModel]
}
Which are then bundled up together into a convenience object for importing
package object implicits extends MyModelSerializer extends FooSerizlier // etc
That way, in Library H, when it performs HTTP calls to various services it just imports implicits from S and then I call Json.validate[MyModel] to get back the models I need from my web services. This is all well and dandy, but I'm working on an application that's running play 2.4 and when I included H into the project and tried to use it I ran up against:
java.lang.NoSuchMethodError: play.api.data.validation.ValidationError.<init>(Ljava/lang/String;Lscala/collection/Seq;)
Which I believe is being caused by play 2.4 using play-json version 2.4.6. Unfortunately, these are a minor version apart and this means that trying to just use the old library like:
// In build.sbt
"com.typesafe.play" %% "play-json" % "2.3.8" force()
Results in all the code in the app to fail to compile because I'm using things like JsError.toJson which weren't parts of play-json 2.3.8. I could change the 14 or so places trying to use that method, but given the exception before I have a feeling that even if I do that it's not going to help.
Around this point I remembered that back in my maven days I could shade dependencies during my build process. So I got to thinking that if I could shade the play-json 2.3.8 dependency in H that that would solve the problem. Since the problem seems to be that calling Json.* in H is using the Json object from play-json 2.4.6.
Unfortunately, the only thing I can find online that indicates the ability to shade is sbt-assembly. I found a great answer on how to do that for a fat jar. But I don't think I can use sbt-assembly because H isn't executable, it's just a library jar. I read through a question like my own but the answer refers to sbt-assembly so it doesn't help me.
Another question seems somewhat promising but I really can't follow how I would use it / where I would be placing the code itself. I also looked through the sbt manual, but nothing stuck out to me as being what I need.
I can't just change S to use play-json 2.4.6 because we're using H in a play 2.3 application as well. So it needs to be able to be used in both.
Right now the only thing I can really think to do if I can't get some kind of shading done is to make H not use S and to instead require some kind of serializer/deserializer implicitly and then wire in the appropriate json (dee)serializer. So here I am asking about how to properly shade with sbt with something that isn't an executable jar because I only want to do a re-write if I absolutely have to. If I missed something (like sbt-assembly being able to shade for non-executable jars as well), I'll take that as an answer if you can point me to the docs I must have missed.
As indicated by Yuval Itzchakov, sbt-assembly doesn't have to be building an executable jar and can shade library code as well. In addition, packing without transitive dependencies except the ones that need to be shaded can be done too and this will keep the packaged jar's size down and let the rest of the dependencies come through as usual.
Hunting down the transitive dependencies manually is what I ended up having to do, but if anyone has a way to do that automatically, that'd be a great addition to this answer. Anyway, this is what I needed to do to the H library's build file to get it properly shading the play-json library.
Figure out what the dependencies are using show compile:dependencyClasspath at the sbt console
Grab anything play related (since I'm only using play-json and no others I can assume play = needs shading)
Also shade the S models because they rely on play-json as well, so to avoid transitive dependencies bringing a non-shadded play 2.3.8 back in, I have to shade my serializers.
Add sbt-assembly to project and then update build.sbt file
build.sbt
//Shade rules for all things play:
assemblyShadeRules in assembly := Seq(
ShadeRule.rename("play.api.**" -> "shade.play.api.#1").inAll
)
//Grabbed from the "publishing" section of the sbt-assembly readme, excluding the "assembly" classifier
addArtifact(artifact in (Compile, assembly), assembly)
// Only the play stuff and the "S" serializers need to be shaded since they use/introduce play:
assemblyExcludedJars in assembly := {
val cp = (fullClasspath in assembly).value
val toIncludeInPackage = Seq(
"play-json_2.11-2.3.8.jar",
"play-datacommons_2.11-2.3.8.jar",
"play-iteratees_2.11-2.3.8.jar",
"play-functional_2.11-2.3.8.jar",
"S_2.11-0.0.0.jar"
)
cp filter {c => !toIncludeInPackage.contains(c.data.getName)}
}
And then I don't get any exceptions anymore from trying to run it. I hope this helps other people with similar issues, and if anyone has a way to automatically grab dependencies and filter by them I'll happily update the answer with it.
I know sbt console will open an interactive Scala REPL and load in all the library dependencies so people can test Scala code right there. However, I wonder if there's anyway to use and treat in a way so that people can interact with my programs directly, instead of interacting with libraries.
For example, if I write a Vector class, how can someone call it from sbt console or any other Scala REPL interface??
Think of it as that you are trying to write a Scala library but you want to provide a simple REPL interface for people to interact with it, like R, instead of asking people to add the library as dependency.
The effect is similar as described here: http://stanford-ppl.github.io/Delite/optiml/getting_started.html
Maybe this will help.
You can use initialCommands key in sbt to do this
So in build.sbt if you put
initialCommands in console := """import my.project._
val myObj = MyObject("Hello", "World")
"""
after you type 'console', you can start using myObj or the classes in my.project
http://www.scala-sbt.org/0.13.5/docs/Howto/scala.html#initial
Yes you can, but you cannot use modified code without reloading the REPL. Just run:
sbt "~ ; console"
And then import your classes with import your.package._ and use them from there.
If you make any changes to your library code, just hit CTRL+D or :quit and it will detect file changes, compile them and enter the REPL again. You can then use the history (navigating with the arrows up/down) to execute anything from the previous session again.
I'm using Groovy for a calculation engine DSL and really like the support we now have in Eclipse with STS and the Groovy-Eclipse plug-in (I'm on STS 2.8.0M2 with latest milestone of Groovy-Eclipse 2.5.2).
One issue I have is I don't know how to get the Groovy editor to 'know' the automatic imports I've added to my script runner, meaning Eclipse gives me a whole bunch of false errors. If you use the Groovy class loader, you can add additional import for 'free', so you avoid needing to do imports in your script.
I've had a play with the DSLD support in Groovy-Eclipse (which can be used to add auto-completion support) but it's not obvious to me that this is something I could do with it - I don't find the DSLD documentation the simplest to follow.
The inferencing settings for Groovy in Eclipse didn't look like the right thing either.
For example:
def result = new CalculationResult()
gives me an error on the CalculationResult class as it's not imported, but the script will execute correctly in my environment because of the customized imports on the Groovy class loader. I'm using the standard import customization provided by Groovy, for example:
import org.codehaus.groovy.control.customizers.ImportCustomizer
import org.codehaus.groovy.control.CompilerConfiguration
def importCustomizer = new ImportCustomizer()
importCustomizer.addImport 'CalculationResult', 'ch.hedgesphere.core.type.CalculationResult'
def configuration = new CompilerConfiguration()
configuration.addCompilationCustomizers(importCustomizer)
...
Any pointers appreciated.
This seems to be in their bugtracker as coming in the 2.6 release of the plugin.
But the comment from Andrew Eisenberg doesn't bode well:
Unfortunately, this is not something that DSLDs can do. Since a
missing import could mean compile errors, we would need a way to
augment the compiler lookup for this. There might be a way to specify
this information inside of a DSLD, but that would mean hooking into
DSLDs in a very different way. More likely, this will have to be
specified through an Eclipse plugin (like the gradle tooling).
Another possibility is that we can ensure that certain kinds of AST
Transforms are applied during a reconcile and so the editor would just
"magically" know about these extra imports. We will have to look into
the feasibility of this, however.
Still, maybe a vote on that issue wouldn't go amiss?
I'm using Scala Source.fromFile however I can't seem to find a nice way of getting it to close the underlying InputStream once the file has been read.
Here's my code that will fail with an AssertionError because the file cannot be deleted.
def main(args : Array[String]) : Unit = {
val myFile = new File("c:/tmp/doodah.txt")
var src = Source.fromFile(myFile)
src.getLines.foreach(l => print(l))
val deleted: Boolean = myFile.delete
assert (deleted , "File was not deleted - maybe the stream hasn't been closed in Source")
}
Source has a method called reset however all that this does is recreate the source from the file.
Internally Source creates an underlying BufferedSource that has a close method. However this is not exposed from Source.
I'd hope that Source would release the file handle once the contents of the file had been read but it doesn't seem to do that.
The best workaround I've seen so far is to essentially cast the Source to a BufferedSource and call close.
try {
src.getLines.foreach(l => print(l))
}
finally src match { case b: scala.io.BufferedSource => b.close }
Alternatively I could create a Source from an InputStream and manage the closing myself.
However this seems somewhat dirty. How are you supposed to release the file handle when using Source?
Scala.io._ is a barebones hack created for the sole purpose of supporting the XML library and the compiler. It is badly designed and suffers from many problems. Scala 2.8 will purport an improved version of it, though hardly anything to write home about.
There is an on-going third party effort by interested parties to develop a sound Scala I/O library. It aims to take home the lessons learned by the JDK7 I/O redesign, while providing an Scala-ish API.
Meanwhile... use Java libraries whenever your application stumbles upon the design problems of the present library.
Works in Scala 2.8.x with a little modification. "getLines" -> "getLines()"
...
src.getLines().foreach(l => print(l))
...
scala.io.Source in 2.8.x is better thought out than its counterpart in 2.7.x and it closes the InputStream correctly.
as far as I can tell io.Source is still broken in 2.8 (connections are leaked etc), so people should be discouraged from using it.
As David suggested above, until the replacement lib http://github.com/scala-incubator/scala-io gets merged (probably after 2.8) the best choice is to relay on pure java libs like apache commons-io etc.