InputStream to a list in Scala - scala

I am trying to read a file as input stream and then convert the contents of the file into a list in scala. Here is my code
val fileStream = getClass.getResourceAsStream("src/main/scala-2.11/com/dc/returnsModel/constants/abc.txt")
val item_urls = Source.fromInputStream(fileStream).getLines.toList
This does now work. I get a NullPointer Exception.
How do I correct this?
However, this works(but I cant use it in a JAR File)
val item_urls = Source.fromFile("src/main/scala-2.11/com/dc/returnsModel/constants/aa.txt").getLines.toList

getClass.getResourceAsStream does not expect a full path, it searches for the requested file in the classpath using the same class loader as the current class.
Fixing this depends a bit on the structure of your project and class that calls this code:
If the class returned by getClass is in the same package as the file you're trying to load (com.dc.returnsModel.constants), then you should simply reference the file name only:
getClass.getResourceAsStream("abc.txt")
If the class returned by getClass resides in a different package, path should start with a / which represents the root of the classpath, hence the package name must follow:
getClass.getResourceAsStream("/com/dc/returnsModel/constants/abc.txt")

You have to provide the correct path starting from root.
Here root is start of your src/scala-2.11 folder in your case.
One example
object SO extends App {
val resourceStream = SO.getClass.getResourceAsStream("/com/sm.txt")
println(Source.fromInputStream(resourceStream).getLines.toList)
}

Related

Is it possible in a Telosys template to call a function created specifically?

I use Telosys (https://www.telosys.org) to generate Python source code and it works fine. But I have a specific need that could be solved by calling a specific conversion function.
Is it possible to create a specific function and to call it inside a Telosys template?
For example: myFunction(“abc”) or $something.myFunction(“abc”) or anything else
If necessary it's possible for me to create this function in different languages ​​like Java, Python or JavaScript.
Telosys is designed to be extensible, so yes you can create your own functions and call them in your templates.
As Telosys is written in Java you will have to create these functions in Java, then use the "loader" object in the ".vm" file to load your class and call the methods defined in this class.
Here's how to do that step by step:
Use your preferred IDE to create a Java class defining your specific method(s). This class can be in any package (including the "default / unnamed package"), the method(s) can be "static" if you don't need an instance of the class.
Compile this class (the goal is to produce a simple ".class" file or a ".jar" file if you prefer)
Put the class (or the jar) in the templates bundle folder :
if you have a ".class" file put it in "classes" folder
if you have a ".jar" file put it in the "lib" folder
Examples :
TelosysTools/templates/my-bundle/classes/MyClass.class
TelosysTools/templates/my-bundle/lib/my-lib.jar
In the template file (".vm") use the "$loader" object to load your Java class and call any of its methods
See "$loader" reference here : http://www.telosys.org/templates-doc/objects/loader.html
If all your methods are “static” you don’t need an instance so just use “$loader.loadClass()”. Example :
## load the class and keep it in a new “$Math” object (no instance created)
#set( $Math = $loader.loadClass("java.lang.Math")
## use the static methods of this class
$Math.random()
If your methods are not “static” so you need an instance, then use “$loader.newInstance()”. Examples :
## create an instance of StringBuilder and put it in the context with #set
#set( $strBuilder = $loader.newInstance('java.lang.StringBuilder') )
## use the instance to call a method
$strBuilder.append('aa')
## create new instance of a specific class : MyTool.class
#set( $tool = $loader.newInstance('MyTool') )
## use the instance to call a method
$tool.myFunction()
So to sum up, you can use any class provided by Java-JRE (eg "Math", “StringBuilder”), you can reuse existing libraries by adding a “.jar” file (don't forget to add dependencies required if the jar file is not stand-alone) or just add a single “.class” file.

ClassNotFoundException when Loading Custom Class

So there's a lot of questions and examples around of reading external .class files using a ClassLoader but I'm struggling to see where I'm going wrong.
val folderUrl: URL = new File("D:/tmp/").toURI.toURL //file:/D:/tmp/
val cl: URLClassLoader = new URLClassLoader(Array(folderUrl), this.getClass.getClassLoader)
cl.loadClass("my.package.MyClassName")
The last line throws a ClassNotFoundException
The folder D:/tmp/ contains a class file "MyClassName.class".
The class has the package "my.package"
The class is called "MyClassName"
I can't understand what I'm doing wrong?
EDIT:
The two closest question which relate are:
Scala - Dynamic object/class loading
How do I call a Scala Object method using reflection?
But these both do not have my problem however, they both get further than I have done where they successfully load the class before running into issues.
So the issue was the fact that the folder structure did not match the package name.
So my folder structure was
D:/tmp/MyClassName.class
The full class name was
my.package.MyClassName
The class loader requires that the folder structure be
D:/tmp/my/package/MyClassName.class

Lemmatiztion with Factorie in SBT

I am writing script in scala to lemmatize some text using wordnetlemmatizer from the this link.
API says lemmatizer object can be created new wordNetLemmatizer(wordnet dir)
How can i pass this input stream of word net dir as parameter to above.
This is my reference.
Any help will be appreciated.
Your link goes to the object WordNetLemmatizer. As you probably now an object is a singleton and you can not do new on an object.
The documentation for the class is here http://factorie.cs.umass.edu/scaladocs/index.html#cc.factorie.app.nlp.lemma.WordNetLemmatizer
The class WordNetLemmatizer offers a constructor with a File, so you can do
new WordNetLemmatizer(new File("/home/xxx/wordnet"))

How do I use an unmanaged dependency in this simple Play example?

I am trying to write a Scala Play web service that returns JSON objects and am having trouble calling a function in a dependency. Can someone tell me what I'm doing wrong in this simplified example?
I have a project called SimpleJSONAPI that consists of the following object.
package com.github.wpm.SimpleJSONAPI
import play.api.libs.json.{JsValue, Json}
object SimpleJSONAPI {
def toJson(s: String): JsValue = Json.toJson(Map("value" -> s))
}
Unit tests confirm that given a string it returns a JSON object of the form {"value":"string"}.
I have a separate Play 2.2.3 Scala project that I created by typing play new PlayJSON. I added the following json action to the controller in the generated application.
package controllers
import play.api.mvc._
import com.github.wpm.SimpleJSONAPI._
object Application extends Controller {
def index = Action {
Ok(views.html.index("Your new application is ready."))
}
def json = {
val j = SimpleJSONAPI.toJson("The JSON API")
Action {
Ok(j)
}
}
}
I also added this route.
GET /json controllers.Application.json
In the root of the PlayJSON project I have a lib directory that contains the simplejsonapi_2.11.jar built by SimpleJSONAPI. This appears to contain the correct code.
> jar tf lib/simplejsonapi_2.11.jar
META-INF/MANIFEST.MF
com/
com/github/
com/github/wpm/
com/github/wpm/SimpleJSONAPI/
com/github/wpm/SimpleJSONAPI/SimpleJSONAPI$.class
com/github/wpm/SimpleJSONAPI/SimpleJSONAPI.class
This compiles, but when I try to connect to localhost:9000/json I get the following runtime error in the line with the val j assignment.
java.lang.NoSuchMethodError: scala.Predef$.ArrowAssoc(L/java/lang/Object;)Ljava/lang/Object;
I've also seen the same error in a unit test that exercises the /json route with a FakeRequest.
If I copy the toJson function from the external dependency into the Play application everything works.
As far as I can tell from the documentation I'm doing everything right, and the error message is opaque. Can someone tell me how to get this to work?
I think your import is incorrect given how you are using the API. Either exclude the object name on the import...
import com.github.wpm.SimpleJSONAPI._
Or change your usage to drop the object name...
val j = toJson("The JSON API")
This was a problem with Scala compiler version compatibility. I compiled my SimpleJSONAPI dependency with Scala 2.11, while the Play app was being built with Scala 2.10. When I changed the SimpleJSONAPI dependency to also build with Scala 2.10, I was able to use it in my Play app.
This was confusing because it's not obvious from the project files which version of Scala a Play app is using, and the error message about ArrowAssoc gives no indication that it is a compiler version issue.

Compiling .as file in Flex SDK that extends a base class

I am simply trying to compile a .as file that extends another .as file like this:
public class BigSquare extends Square{
...
}
I go to the command line and type:
mxmlc BigSquare.as
The error I get is "The definition of base class Square was not found."
Where do I need to place the base class Square.as in order for BigSquare.as to compile?
You should add to the command line parameters the "-source-path" with the path to the other files you use at compile time (i.e. Square.as). More information here: http://livedocs.adobe.com/flex/3/html/help.html?content=compilers_13.html . You call should look like this
mxmlxc -source-path "path/to/Square.as" BigSquare.as
Hope it helps.