Why doesn't Scala Source close the underlying InputStream? - scala

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.

Related

How to write a value from the response to a file in Gatling?

I have a script which creates new referenceId each time its executed. I used
.check(regex("orders.(.*?)\"").saveAs("referenceId")))
to extract the referenceId. Now, how can I write/append it to a file without impacting the script even if I run it as a load test?
I used session in .exec to write my value into a file. Here it is:
.exec( session => {
scala.tools.nsc.io.File("../user-files/data/refenceId.csv").appendAll(session("refenceId").as[String]+"\n")
session}
)
You solution works, but...
First of all do not use anything (if you don't have to) from scala.tools.nsc.io package. It is internal package only for Scala compiler. It is not public API included in Scala runtime library (official Scaladoc). More about the topic here. Scala do not have any own abstraction for writing to file, hence one need to use normal java.io.File & co.
Secondly opening a file in each execution can (may not) slow down your load-test. It strongly depends on at which rate you are making the requests. At higher rates you can experience contention when more concurrent executions will be trying to write to same file. Simplest solution to this is to write to different files, but you can still run out of maximum possible number of opened files. Another solution is to use shared java.io.FileOutputStream resp. java.io.FileWriter to desired target file with proper synchronisation (will be accessed from various threads), which is still blocking IO. Yet another solution will be use Java NIO API to write to shared file via Channel (non-blocking) or OutputStream (not sure if non-blocking).
Of course solutions differ in difficulty of implementation.

Typesafe config programmatic modification and persistence

Typesafe Config documentation and library examples make a point that type safety can be achieved by making a configuration object or nested objects with getter methods mapped to Config.getType(key) methods.
If I wrap config calls in something like this:
class MyConfig (cfg:Config) {
val language = cfg.getString("app.language")
val database = new {
val url = cfg.getString("db.url")
val port = cfg.getInt("db.port")
...
}
}
I can do decent looking calls like config.database.url. Neat. (That dot looks so much greater than underscore)
What I don't quite get is how to allow modifying properties and saving them - quoting documentation, config is immutable. My attempts so far turned into either a gross spaghetti (closures with var config) or horrendous boilerplate (modifying a plain object and creating a new config from it to save), so I turned here for help.
I'd appreciate if someone showed me a good pattern for programmatically modifiable configuration using Typesafe Config.
It is possible that Typesafe Config just isn't a right tool for the job. I have little use for it's powerful merging and inheritance capabilities, instead I mostly need a simple, concise, unicode-friendly and type-safe way to load and store properties. I already do have one, a reflection-based java lib working with annotated POJOs. Doesn't seem to be a lot of variety with configuration libraries in Scala. I may have been too eager to throw away my trusty java tools.

Build a scala interpreter in the browser

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

Issue with BufferedReader.readLine using sbt run or sbt console

My question is quick I'm working on a small console for reading input in and then calling the appropriate code. I'm using sbt and I've encountered an issue where when I try to read input after running my program with sbt run, inside sbt console, or even in the plain old scala interpreter.
The prompt appears to just hang, but if I hit return it does actually read the input in. Though the shell's buffer remains empty. Here is the general code I've been trying that has been giving me the issue.
import java.io._
val s = new BufferedReader(new InputStreamReader(System.in))
val line = s.readLine
println(line)
Does anyone know why this is, and if so is there a way to fix this? I would love to be able to see what I type when I run my program from sbt. Without seeing my typing in the shell it makes the testing and development of my project much less enjoyable.
This is really a Java API question, although in Scala. BufferedReader.readLine() will consume all the characters you type from System.in until it has a whole line, at which time it will return the line as you said.
Console input was difficult in Java with the original java.io classes. Prior to Java6, I've seen a couple of messy solutions to this, but fortunately a new class was introduced with that release to make it much easier: java.io.Console. I think it then becomes as simple as
val line = System.console.readLine
println(line)

In Scala, can I call Source.reset() on resources read from the classpath?

Suppose I have a jarfile on my classpath. In that jarfile I have a file afile.txt.
I need to iterate on that file twice, once to count the lines and once to parse it. This is what I did:
val source = Source.fromInputStream(/*some magic to get the resource's InputStream*/)
source.getLines.foreach (/*count the lines*/)
source.getLines.reset.foreach (/*do something interesting*/)
But this doesn't work. In the debugger it looks like the call to reset() returns an empty iterator. The code above works fine when the Source refers to a file on the filesystem instead of on the classpath.
Am I doing something wrong, or is this a bug in Scala's io library?
I think this is a bug is the Scala library. I had a quick look at Source.scala in 2.8 trunk and reset seems to return a new wrapper around the original input stream which would have no content left after the first pass. I think it should throw an exception. I can't think of a straightforward way you could reset an arbitrary input stream.
I think you can simply call val source2 = Source.fromInputStream and read again, as it seems reset does not do more than that.