How to run generated frege java code on jvm? - java

hello world in haskell frege :
hello.fr :
module Hello where
main args = do
putStrLn "Hello, World!"
This code generates hello.java :
/*
Source code is in UTF-8 encoding. The following symbols may appear, among others:
α β γ δ ε ζ η θ ι κ λ μ ν ξ ο π ρ ς σ τ υ φ χ ψ ω « • ¦ » ∀ ∃ ∷ … → ← fi fl ƒ
If you can't read this, you're out of luck. This code was generated with the frege compiler version 3.24.80
from hello.fr Do not edit this file! Instead, edit the source file and recompile.
*/
import frege.run8.Func;
import frege.run8.Lazy;
import frege.run8.Thunk;
import frege.run.Kind;
import frege.run.RunTM;
import frege.runtime.Meta;
import frege.runtime.Phantom.RealWorld;
import frege.Prelude;
import frege.control.Category;
import frege.control.Semigroupoid;
import frege.java.IO;
import frege.java.Lang;
import frege.java.Util;
import frege.java.util.Regex;
import frege.prelude.Maybe;
import frege.prelude.PreludeArrays;
import frege.prelude.PreludeBase;
import frege.prelude.PreludeIO;
import frege.prelude.PreludeList;
import frege.prelude.PreludeMonad;
import frege.prelude.PreludeText;
#SuppressWarnings("unused")
#Meta.FregePackage(
source="hello.fr", time=1470398249962L, jmajor=1, jminor=8,
imps={
"frege.Prelude", "frege.prelude.PreludeArrays", "frege.prelude.PreludeBase", "frege.prelude.PreludeIO",
"frege.prelude.PreludeList", "frege.prelude.PreludeMonad", "frege.prelude.PreludeText", "frege.java.util.Regex"
},
nmss={"Prelude", "PreludeArrays", "PreludeBase", "PreludeIO", "PreludeList", "PreludeMonad", "PreludeText", "Regexp"},
symas={}, symcs={}, symis={}, symts={},
symvs={#Meta.SymV(offset=20, name=#Meta.QName(pack="Hello", base="main"), stri="s(u)", sig=1, depth=1, rkind=49)},
symls={},
taus={
#Meta.Tau(kind=2, suba=0, tcon={#Meta.QName(kind=0, pack="frege.prelude.PreludeBase", base="[]")}),
#Meta.Tau(kind=2, suba=0, tcon={#Meta.QName(kind=0, pack="frege.prelude.PreludeBase", base="StringJ")}),
#Meta.Tau(kind=2, suba=0, tcon={#Meta.QName(kind=0, pack="frege.prelude.PreludeBase", base="Char")}),
#Meta.Tau(kind=0, suba=1, subb=2), #Meta.Tau(kind=0, suba=0, subb=3),
#Meta.Tau(kind=2, suba=0, tcon={#Meta.QName(kind=0, pack="frege.prelude.PreludeBase", base="ST")}),
#Meta.Tau(kind=2, suba=0, tcon={#Meta.QName(kind=0, pack="frege.prelude.PreludeBase", base="RealWorld")}),
#Meta.Tau(kind=0, suba=5, subb=6),
#Meta.Tau(kind=2, suba=0, tcon={#Meta.QName(kind=0, pack="frege.prelude.PreludeBase", base="()")}),
#Meta.Tau(kind=0, suba=7, subb=8)
},
rhos={#Meta.Rho(rhofun=false, rhotau=4), #Meta.Rho(rhofun=false, rhotau=9), #Meta.Rho(sigma=0, rhotau=1)},
sigmas={#Meta.Sigma(rho=0), #Meta.Sigma(rho=2)}, exprs={#Meta.Expr()}
)
final public class Hello {
final public static Func.U<RealWorld, Short> $main(final Lazy<PreludeBase.TList<String/*<Character>*/>> arg$1) {
return Prelude.putStrLn("Hello, World!");
}
public static void main(final java.lang.String[] argv) {
try {
frege.run.RunTM.argv = argv;
PreludeBase.TST.<Short>performUnsafe($main
(Thunk.lazy(PreludeArrays.IListSource_JArray.<String/*<Character>*/>toList(argv)))
).call();
frege.runtime.Runtime.stdout.get().close();
frege.runtime.Runtime.stderr.get().close();
} finally { frege.run.Concurrent.shutDownIfExists(); }
}
}
I then compile the generated java code with no error :
javac -cp frege3.jar build/Hello.class
I then attempt to run the code :
cd build
java Hello
But this returns an error :
Error: A JNI error has occurred, please check your installation and try again
Exception in thread "main" java.lang.NoClassDefFoundError: frege/run8/Lazy
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2701)
at java.lang.Class.privateGetMethodRecursive(Class.java:3048)
at java.lang.Class.getMethod0(Class.java:3018)
at java.lang.Class.getMethod(Class.java:1784)
at sun.launcher.LauncherHelper.validateMainClass(LauncherHelper.java:544)
at sun.launcher.LauncherHelper.checkAndLoadMain(LauncherHelper.java:526)
Caused by: java.lang.ClassNotFoundException: frege.run8.Lazy
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 7 more
How to run the generated frege java code on jvm ?
I'm using java8

You need to add frege3.jar in your classpath also when you launch the command, so try this:
java -cp .:frege3.jar Hello
Assuming that frege3.jar and Hello.class are both in the current directory

You don't need an extra javac compilation, this is automatically done by the frege compiler (unless suppressed by a flag).
Yes, there is a getting started document here: https://github.com/Frege/frege/wiki/Getting-Started

Related

Drools Function unable to resolve method using strict-mode

I have a Drools file that I'm using for business logic on a Tomcat6 server running Java 1.7.0_131 inside a Docker container. When I run the code bellow:
package org.fosstrak.capturingapp
import org.fosstrak.capturingapp.util.Util;
import org.fosstrak.ale.xsd.ale.epcglobal.ECReport;
import org.fosstrak.ale.xsd.ale.epcglobal.ECReports;
import org.fosstrak.ale.xsd.ale.epcglobal.ECReportGroupListMember;
import org.fosstrak.ale.xsd.epcglobal.EPC;
import org.fosstrak.capturingapp.util.SimpleEPCISDocument;
import org.fosstrak.epcis.model.ActionType;
import java.util.List;
import java.util.LinkedList;
import function org.fosstrak.capturingapp.util.Util.extractEPC;
import function org.fosstrak.capturingapp.util.Util.extractReportMembers;
// the global collector for all the EPCIS documents for further processing.
global java.util.List epcisResults
function List warehouseReportHandler(List reports, String reportName){
// List of ECReports
List epcs = new LinkedList();
for(Object rs : reports){
if(rs instanceof ECReports){
ECReports rsc = (ECReports) rs;
for(ECReport report : rsc.getReports().getReport()){
if(report.getReportName() == reportName){
ecps.addAll(extractEPC(Util.selectTag, report));
}
}
}
}
return epcs;
}
rule "ADDITIONS Rule Tags from reader 'Reader_Warehouse_Shelve1' from the specName 'ECSpec'"
dialect "java"
when
$reports : ECReports( reports != null)
$epcs : LinkedList( size > 0 ) from collect (
EPC() from warehouseReportHandler($reports, "additions")
)
then
SimpleEPCISDocument simpleDocument = new SimpleEPCISDocument();
simpleDocument.addObjectEvent(
$epcs,
ActionType.OBSERVE,
"urn:epcglobal:cbv:bizstep:storing",
"urn:epcglobal:cbv:disp:sellable_not_accessible",
"urn:epc:id:sgln:76300544.00000.1",
"urn:epc:id:sgln:76300544.00000.0"
);
System.out.println("\n=====================================================");
System.out.println("Additions tags seen:");
for (Object o : $epcs) System.out.println(((EPC)o).getValue());
System.out.println("=====================================================\n");
epcisResults.add(simpleDocument.getDocument());
end
I get the following error message:
21146 [Thread-2] DEBUG org.fosstrak.capturingapp.ECReportsHandler - Unable to build expression for 'from' : Failed to compile: 1 compilation error(s):
capture | - (1,45) unable to resolve method using strict-mode: java.lang.Object.warehouseReportHandler(org.fosstrak.ale.xsd.ale.epcglobal.ECReports, java.lang.String) 'warehouseReportHandler($reports, "additions")' : [Rule name='ADDITIONS Rule Tags from reader 'Reader_Warehouse_Shelve1' from the specName 'ECSpec'']
capture | Error importing : 'org.fosstrak.capturingapp.WarehouseReportHandler.warehouseReportHandler'[ warehouseReportHandler : Function Compilation error
capture | warehouseReportHandler (line:28): ecps cannot be resolved
capture | ][ warehouseReportHandler : Function Compilation error
capture | warehouseReportHandler (line:28): ecps cannot be resolved
capture | ]Rule Compilation error : [Rule name='ADDITIONS Rule Tags from reader 'Reader_Warehouse_Shelve1' from the specName 'ECSpec'']
capture | org/fosstrak/capturingapp/Rule_ADDITIONS_Rule_Tags_from_reader__Reader_Warehouse_Shelve1__from_the_specName__ECSpec__0.java (2:489) : The import org.fosstrak.capturingapp.WarehouseReportHandler cannot be resolved
I'm new to Drools. I am not sure if it's a syntax problem.
Update: I've removed the generics I had previously and tried to follow the examples given in the project, without success. (https://github.com/Fosstrak/fosstrak/tree/master/capturingapp/trunk/src/main/resources/drools)
Thank you everyone for your time
This line
function List warehouseReportHandler(List reports, String reportName){
defines the function with the parameter as a list. However the invocation
$reports : ECReports( reports != null)
$epcs : LinkedList( size > 0 ) from collect (
EPC() from warehouseReportHandler($reports, "additions")
)
shows a parameter of type ECReports is being sent in to the method. Can you fix this and try?

how can solve java exception error [duplicate]

This question already has answers here:
Why am I getting a NoClassDefFoundError in Java?
(31 answers)
Closed 4 years ago.
I,m working in eclipse with java language but i have error when write the
POS standford api code for tagging the text. plz, can any one help me , the
error as follow
"Exception in thread "main" java.lang.NoClassDefFoundError:
org/slf4j/LoggerFactory at edu.stanford.nlp.pipeline.StanfordCoreNLP.
(StanfordCore.<clinit>(StanfordCoreNLP.java:99)
at tweetfileanalysis.TweetPOS.tweettag(TweetPOS.java:23)
at tweetfileanalysis.ReadJson.readJsonf(ReadJson.java:288)
at tweetfileanalysis.Mainclass.main(Mainclass.java:17)
Caused by: java.lang.ClassNotFoundException: org.slf4j.LoggerFactory
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(Unknown Source)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(Unknown
Source)
at java.base/java.lang.ClassLoader.loadClass(Unknown Source)
... 4 more
i put all libraries by using configure build path so what can i do to solve the error the class code as follow:
package tweetfileanalysis;
import edu.stanford.nlp.ie.util.RelationTriple;
import edu.stanford.nlp.ling.CoreAnnotations;
import edu.stanford.nlp.pipeline.Annotation;
import edu.stanford.nlp.pipeline.StanfordCoreNLP;
import edu.stanford.nlp.naturalli.NaturalLogicAnnotations;
import edu.stanford.nlp.util.CoreMap;
import java.util.Collection;
import java.util.Properties;
public class TweetPOS{
public TweetPOS()
{}
public static void tweettag(String tweet)
{
// Create the Stanford CoreNLP pipeline
Properties props = new Properties();
props.getProperty("annotators",
"tokenize,ssplit,pos,lemma,depparse,natlog,openie");
StanfordCoreNLP pipeline = new StanfordCoreNLP(props);
// Annotate an example document.
Annotation doc = new Annotation("Obama was born in Hawaii. He is our
president.");
pipeline.annotate(doc);
System.out.println("fhfbg");
// Loop over sentences in the document
for (CoreMap sentence :
doc.get(CoreAnnotations.SentencesAnnotation.class)) {
// Get the OpenIE triples for the sentence
Collection<RelationTriple> triples =
sentence.get(NaturalLogicAnnotations.RelationTriplesAnnotation.class);
// Print the triples
System.out.println("uuuuuuuuuuuuuuuuuuu");
for (RelationTriple triple : triples) {
System.out.println(triple.confidence + "\t" +
triple.subjectLemmaGloss() + "\t" +
triple.relationLemmaGloss() + "\t" +
triple.objectLemmaGloss());
}
}
}
}
Download slf4j.jar here and config your build path.

Unable to run python file in java

I have to call example.py (having another dependencies windrose, matlab, numpy ) python file from java to create wind graph but it unable to import any dependency while calling from java but its runs fine independently using python, I got
Error: no module name windrose
but this module is already in folder please let me know how to do it
windroseGraph ie = new windroseGraph();
ie.execfile("E:\\example.py");
PyInstance hello = ie.createClass("test", "None");
hello.invoke("run");
python file example.py
from windrose import WindroseAxes
from numpy.random import random
from numpy import arange
from matplotlib import pyplot as plt
import matplotlib.cm as cm
class test:
def new_axes():
fig = plt.figure(figsize=(8, 8), dpi=80, facecolor='w', edgecolor='w')
rect = [0.1, 0.1, 0.8, 0.8]
ax = WindroseAxes(fig, rect, axisbg='w')
fig.add_axes(ax)
return ax
def set_legend(ax):
l = ax.legend(borderaxespad=-0.10)
plt.setp(l.get_texts(), fontsize=8)
def run(self,wd,ws):
ax = new_axes()
ax.bar(wd, ws, normed=True, opening=0.8, edgecolor='white')
set_legend(ax)
##print ax._info
plt.show()
example.py is python file having function with parameter and generate wind graph using windrose.py module (python lib online available )

Scala: for loop: iterating over a a directory stream

Update:
I have written the following updated code after inputs from Scala experts here.
Here below is the updated code.
The code compiles, but on "run" throws an IllegalStateException: I posted the error stacktrace after the code listing:
import java.io.IOException
import java.nio.file.FileSystems
import java.nio.file.FileVisitOption
import java.nio.file.FileVisitResult
import java.nio.file.FileVisitor
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
import java.nio.file.attribute.BasicFileAttributes
import java.util.EnumSet
import java.nio.file.{DirectoryStream,DirectoryIteratorException}
import scala.collection.JavaConversions._
class TestFVis(val searchPath: Path) extends FileVisitor[Path] {
//Here I provide implementations for postVisitDirectory,
//preVisitDirectory, visitFile, and visitFileFailed
}
object Main {
def main(args: Array[String]) {
val searchFileOrFolder: Path = Paths.get("C://my_dir")
println("The Path object is: " + searchFileOrFolder)
var testFileVisitorTop = new TestFVis(searchFileOrFolder)
println("Our top level FileVisitor is: " + testFileVisitorTop)
val opts = EnumSet.of(FileVisitOption.FOLLOW_LINKS)
val rootDirsIterable: Iterable[Path] = FileSystems.getDefault.getRootDirectories //returns the default filesystem
// and then returns an Iterable[Path] to iterate over the paths of the root directories
var dirStream:Option[DirectoryStream[Path]] = None
for(rootDir <- rootDirsIterable) {
println("in the Outer For")
dirStream= Some(Files.newDirectoryStream(searchFileOrFolder))
def dstream = dirStream.get
val streamIter = dstream.iterator().filter((path) => {
Files.isRegularFile(path)
})
for( dirStreamUnwrapped <- dirStream;(filePath:Path) <- dirStreamUnwrapped) {
//for( (filePath: DirectoryStream[Path]) <- dirStream) {
val tempPath = Files.walkFileTree(filePath, testFileVisitorTop)
//val tempPath = Files.walkFileTree(fileOrDir,opts,Integer.MAX_VALUE,testFileVisitorTop)
println("current path is: " + tempPath)
if (!testFileVisitorTop.found) {
println("The file or folder " + searchFileOrFolder+ " was not found!")
}
}
}
}
}
However for historical context here is the compile error I got at first:
[error] found : java.nio.file.Path => Unit
[error] required: java.nio.file.DirectoryStream[java.nio.file.Path] => ?
[error] for((filePath:Path) <- dirStream) {
--
After changing the code:
The code compiles with no errors, but I get an IllegalStateException on sbt 'run'\
> run
ur top level FileVisitor is C:\my_dir
Our top level FileVisitor is: com.me.ds.TestFileVisitor
#5564baf6
in the Outer For
[error] (run-main-0) java.lang.IllegalStateException: Iterator already obtained
java.lang.IllegalStateException: Iterator already obtained
at sun.nio.fs.WindowsDirectoryStream.iterator(WindowsDirectoryStream.jav
a:117)
at scala.collection.convert.Wrappers$JIterableWrapper.iterator(Wrappers.
scala:54)
at scala.collection.IterableLike$class.foreach(IterableLike.scala:72)
at scala.collection.AbstractIterable.foreach(Iterable.scala:54)
at scala.collection.TraversableLike$WithFilter.foreach(TraversableLike.s
cala:777)
at com.me.ds.Main$$anonfun$main$1$$anonfun$appl
y$1.apply(SampleFileVis.scala:76)
at com.me.ds.Main$$anonfun$main$1$$anonfun$appl
y$1.apply(AFileVisitor.scala:76)
at scala.Option.foreach(Option.scala:256)
at **com.me.ds.Main$$anonfun$main$1.apply(SampleFileVisitor.scala:76)**
at com.me.ds.Main$$anonfun$main$1.apply(AFileVi
sitor.scala:68)
at scala.collection.Iterator$class.foreach(Iterator.scala:743)
at scala.collection.AbstractIterator.foreach(Iterator.scala:1195)
at scala.collection.IterableLike$class.foreach(IterableLike.scala:72)
at scala.collection.AbstractIterable.foreach(Iterable.scala:54)
at com.me.ds.Main$.main(SampleFileVis.scala:68)
at com.me.ds.Main.main(SampleFileVis.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.
java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAcces
sorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:483)
[trace] Stack trace suppressed: run last compile:run for the full output.
java.lang.RuntimeException: Nonzero exit code: 1
at scala.sys.package$.error(package.scala:27)
[trace] Stack trace suppressed: run last compile:run for the full output.
[error] (compile:run) Nonzero exit code: 1
[error] Total time: 0 s, completed Mar 24, 2015 7:32:38 AM
>
=-------------
I am going out and investigating the error on my own also. If someone can point me in the right direction here that would make my code compile and run, I would have accomplished my goal here.
thanks
All you are doing with the first for is unwrapping the Option, which cannot be cast to a Path. You just need to take your unwrapped object and use it in the next part:
for(dirStreamUnwrapped <- dirStream;
(filePath:Path) <- dirStreamUnwrapped) {
val tempPath = Files.walkFileTree(filePath, testFVis)
}
object needs to be lowercase.
dirStream needs to be preceded by val.
you have too many } at the end.
you have new TestFileVisitor but you meant new TestFVis.
dirStream has type: Some[DirectoryStream[Path]], which means that you need (filePath: DirectoryStream[Path]) <- dirStream

java.lang.NullPointerException in OpenNLP using RJB (Ruby Java Bridge)

I am trying to use the open-nlp Ruby gem to access the Java OpenNLP processor through RJB (Ruby Java Bridge). I am not a Java programmer, so I don't know how to solve this. Any recommendations regarding resolving it, debugging it, collecting more information, etc. would be appreciated.
The environment is Windows 8, Ruby 1.9.3p448, Rails 4.0.0, JDK 1.7.0-40 x586. Gems are rjb 1.4.8 and louismullie/open-nlp 0.1.4. For the record, this file runs in JRuby but I experience other problems in that environment and would prefer to stay native Ruby for now.
In brief, the open-nlp gem is failing with java.lang.NullPointerException and Ruby error method missing. I hesitate to say why this is happening because I don't know, but it appears to me that the dynamic loading of the Jars file opennlp.tools.postag.POSTaggerME#1b5080a cannot be accessed, perhaps because OpenNLP::Bindings::Utils.tagWithArrayList isn't being set up correctly. OpenNLP::Bindings is Ruby. Utils, and its methods, are Java. And Utils is supposedly the "default" Jars and Class files, which may be important.
What am I doing wrong, here? Thanks!
The code I am running is copied straight out of github/open-nlp. My copy of the code is:
class OpennlpTryer
$DEBUG=false
# From https://github.com/louismullie/open-nlp
# Hints: Dir.pwd; File.expand_path('../../Gemfile', __FILE__);
# Load the module
require 'open-nlp'
#require 'jruby-jars'
=begin
# Alias "write" to "print" to monkeypatch the NoMethod write error
java_import java.io.PrintStream
class PrintStream
java_alias(:write, :print, [java.lang.String])
end
=end
=begin
# Display path of jruby-jars jars...
puts JRubyJars.core_jar_path # => path to jruby-core-VERSION.jar
puts JRubyJars.stdlib_jar_path # => path to jruby-stdlib-VERSION.jar
=end
puts ENV['CLASSPATH']
# Set an alternative path to look for the JAR files.
# Default is gem's bin folder.
# OpenNLP.jar_path = '/path_to_jars/'
OpenNLP.jar_path = File.join(ENV["GEM_HOME"],"gems/open-nlp-0.1.4/bin/")
puts OpenNLP.jar_path
# Set an alternative path to look for the model files.
# Default is gem's bin folder.
# OpenNLP.model_path = '/path_to_models/'
OpenNLP.model_path = File.join(ENV["GEM_HOME"],"gems/open-nlp-0.1.4/bin/")
puts OpenNLP.model_path
# Pass some alternative arguments to the Java VM.
# Default is ['-Xms512M', '-Xmx1024M'].
# OpenNLP.jvm_args = ['-option1', '-option2']
OpenNLP.jvm_args = ['-Xms512M', '-Xmx1024M']
# Redirect VM output to log.txt
OpenNLP.log_file = 'log.txt'
# Set default models for a language.
# OpenNLP.use :language
OpenNLP.use :english # Make sure this is lower case!!!!
# Simple tokenizer
OpenNLP.load
sent = "The death of the poet was kept from his poems."
tokenizer = OpenNLP::SimpleTokenizer.new
tokens = tokenizer.tokenize(sent).to_a
# => %w[The death of the poet was kept from his poems .]
puts "Tokenize #{tokens}"
# Maximum entropy tokenizer, chunker and POS tagger
OpenNLP.load
chunker = OpenNLP::ChunkerME.new
tokenizer = OpenNLP::TokenizerME.new
tagger = OpenNLP::POSTaggerME.new
sent = "The death of the poet was kept from his poems."
tokens = tokenizer.tokenize(sent).to_a
# => %w[The death of the poet was kept from his poems .]
puts "Tokenize #{tokens}"
tags = tagger.tag(tokens).to_a
# => %w[DT NN IN DT NN VBD VBN IN PRP$ NNS .]
puts "Tags #{tags}"
chunks = chunker.chunk(tokens, tags).to_a
# => %w[B-NP I-NP B-PP B-NP I-NP B-VP I-VP B-PP B-NP I-NP O]
puts "Chunks #{chunks}"
# Abstract Bottom-Up Parser
OpenNLP.load
sent = "The death of the poet was kept from his poems."
parser = OpenNLP::Parser.new
parse = parser.parse(sent)
=begin
parse.get_text.should eql sent
parse.get_span.get_start.should eql 0
parse.get_span.get_end.should eql 46
parse.get_child_count.should eql 1
=end
child = parse.get_children[0]
child.text # => "The death of the poet was kept from his poems."
child.get_child_count # => 3
child.get_head_index #=> 5
child.get_type # => "S"
puts "Child: #{child}"
# Maximum Entropy Name Finder*
OpenNLP.load
# puts File.expand_path('.', __FILE__)
text = File.read('./spec/sample.txt').gsub!("\n", "")
tokenizer = OpenNLP::TokenizerME.new
segmenter = OpenNLP::SentenceDetectorME.new
puts "Tokenizer: #{tokenizer}"
puts "Segmenter: #{segmenter}"
ner_models = ['person', 'time', 'money']
ner_finders = ner_models.map do |model|
OpenNLP::NameFinderME.new("en-ner-#{model}.bin")
end
puts "NER Finders: #{ner_finders}"
sentences = segmenter.sent_detect(text)
puts "Sentences: #{sentences}"
named_entities = []
sentences.each do |sentence|
tokens = tokenizer.tokenize(sentence)
ner_models.each_with_index do |model, i|
finder = ner_finders[i]
name_spans = finder.find(tokens)
name_spans.each do |name_span|
start = name_span.get_start
stop = name_span.get_end-1
slice = tokens[start..stop].to_a
named_entities << [slice, model]
end
end
end
puts "Named Entities: #{named_entities}"
# Loading specific models
# Just pass the name of the model file to the constructor. The gem will search for the file in the OpenNLP.model_path folder.
OpenNLP.load
tokenizer = OpenNLP::TokenizerME.new('en-token.bin')
tagger = OpenNLP::POSTaggerME.new('en-pos-perceptron.bin')
name_finder = OpenNLP::NameFinderME.new('en-ner-person.bin')
# etc.
puts "Tokenizer: #{tokenizer}"
puts "Tagger: #{tagger}"
puts "Name Finder: #{name_finder}"
# Loading specific classes
# You may want to load specific classes from the OpenNLP library that are not loaded by default. The gem provides an API to do this:
# Default base class is opennlp.tools.
OpenNLP.load_class('SomeClassName')
# => OpenNLP::SomeClassName
# Here, we specify another base class.
OpenNLP.load_class('SomeOtherClass', 'opennlp.tools.namefind')
# => OpenNLP::SomeOtherClass
end
The line which is failing is line 73: (tokens == the sentence being processed.)
tags = tagger.tag(tokens).to_a #
# => %w[DT NN IN DT NN VBD VBN IN PRP$ NNS .]
tagger.tag calls open-nlp/classes.rb line 13, which is where the error is thrown. The code there is:
class OpenNLP::POSTaggerME < OpenNLP::Base
unless RUBY_PLATFORM =~ /java/
def tag(*args)
OpenNLP::Bindings::Utils.tagWithArrayList(#proxy_inst, args[0]) # <== Line 13
end
end
end
The Ruby error thrown at this point is: `method_missing': unknown exception (NullPointerException). Debugging this, I found the error java.lang.NullPointerException. args[0] is the sentence being processed. #proxy_inst is opennlp.tools.postag.POSTaggerME#1b5080a.
OpenNLP::Bindings sets up the Java environment. For example, it sets up the Jars to be loaded and the classes within those Jars. In line 54, it sets up defaults for RJB, which should set up OpenNLP::Bindings::Utils and its methods as follows:
# Add in Rjb workarounds.
unless RUBY_PLATFORM =~ /java/
self.default_jars << 'utils.jar'
self.default_classes << ['Utils', '']
end
utils.jar and Utils.java are in the CLASSPATH with the other Jars being loaded. They are being accessed, which is verified because the other Jars throw error messages if they are not present. The CLASSPATH is:
.;C:\Program Files (x86)Java\jdk1.7.0_40\lib;C:\Program Files (x86)Java\jre7\lib;D:\BitNami\rubystack-1.9.3-12\ruby\lib\ruby\gems\1.9.1\gems\open-nlp-0.1.4\bin
The applications Jars are in D:\BitNami\rubystack-1.9.3-12\ruby\lib\ruby\gems\1.9.1\gems\open-nlp-0.1.4\bin and, again, if they are not there I get error messages on other Jars. The Jars and Java files in ...\bin include:
jwnl-1.3.3.jar
opennlp-maxent-3.0.2-incubating.jar
opennlp-tools-1.5.2-incubating.jar
opennlp-uima-1.5.2-incubating.jar
utils.jar
Utils.java
Utils.java is as follows:
import java.util.Arrays;
import java.util.ArrayList;
import java.lang.String;
import opennlp.tools.postag.POSTagger;
import opennlp.tools.chunker.ChunkerME;
import opennlp.tools.namefind.NameFinderME; // interface instead?
import opennlp.tools.util.Span;
// javac -cp '.:opennlp.tools.jar' Utils.java
// jar cf utils.jar Utils.class
public class Utils {
public static String[] tagWithArrayList(POSTagger posTagger, ArrayList[] objectArray) {
return posTagger.tag(getStringArray(objectArray));
}
public static Object[] findWithArrayList(NameFinderME nameFinder, ArrayList[] tokens) {
return nameFinder.find(getStringArray(tokens));
}
public static Object[] chunkWithArrays(ChunkerME chunker, ArrayList[] tokens, ArrayList[] tags) {
return chunker.chunk(getStringArray(tokens), getStringArray(tags));
}
public static String[] getStringArray(ArrayList[] objectArray) {
String[] stringArray = Arrays.copyOf(objectArray, objectArray.length, String[].class);
return stringArray;
}
}
So, it should define tagWithArrayList and import opennlp.tools.postag.POSTagger. (OBTW, just to try, I changed the incidences of POSTagger to POSTaggerME in this file. It changed nothing...)
The tools Jar file, opennlp-tools-1.5.2-incubating.jar, includes postag/POSTagger and POSTaggerME class files, as expected.
Error messages are:
D:\BitNami\rubystack-1.9.3-12\ruby\bin\ruby.exe -e $stdout.sync=true;$stderr.sync=true;load($0=ARGV.shift) D:/BitNami/rubystack-1.9.3-12/projects/RjbTest/app/helpers/opennlp_tryer.rb
.;C:\Program Files (x86)\Java\jdk1.7.0_40\lib;C:\Program Files (x86)\Java\jre7\lib;D:\BitNami\rubystack-1.9.3-12\ruby\lib\ruby\gems\1.9.1\gems\open-nlp-0.1.4\bin
D:/BitNami/rubystack-1.9.3-12/ruby/lib/ruby/gems/1.9.1/gems/open-nlp-0.1.4/bin/
D:/BitNami/rubystack-1.9.3-12/ruby/lib/ruby/gems/1.9.1/gems/open-nlp-0.1.4/bin/
Tokenize ["The", "death", "of", "the", "poet", "was", "kept", "from", "his", "poems", "."]
Tokenize ["The", "death", "of", "the", "poet", "was", "kept", "from", "his", "poems", "."]
D:/BitNami/rubystack-1.9.3-12/ruby/lib/ruby/gems/1.9.1/gems/open-nlp-0.1.4/lib/open-nlp/classes.rb:13:in `method_missing': unknown exception (NullPointerException)
from D:/BitNami/rubystack-1.9.3-12/ruby/lib/ruby/gems/1.9.1/gems/open-nlp-0.1.4/lib/open-nlp/classes.rb:13:in `tag'
from D:/BitNami/rubystack-1.9.3-12/projects/RjbTest/app/helpers/opennlp_tryer.rb:73:in `<class:OpennlpTryer>'
from D:/BitNami/rubystack-1.9.3-12/projects/RjbTest/app/helpers/opennlp_tryer.rb:1:in `<top (required)>'
from -e:1:in `load'
from -e:1:in `<main>'
Modified Utils.java:
import java.util.Arrays;
import java.util.Object;
import java.lang.String;
import opennlp.tools.postag.POSTagger;
import opennlp.tools.chunker.ChunkerME;
import opennlp.tools.namefind.NameFinderME; // interface instead?
import opennlp.tools.util.Span;
// javac -cp '.:opennlp.tools.jar' Utils.java
// jar cf utils.jar Utils.class
public class Utils {
public static String[] tagWithArrayList(POSTagger posTagger, Object[] objectArray) {
return posTagger.tag(getStringArray(objectArray));
}f
public static Object[] findWithArrayList(NameFinderME nameFinder, Object[] tokens) {
return nameFinder.find(getStringArray(tokens));
}
public static Object[] chunkWithArrays(ChunkerME chunker, Object[] tokens, Object[] tags) {
return chunker.chunk(getStringArray(tokens), getStringArray(tags));
}
public static String[] getStringArray(Object[] objectArray) {
String[] stringArray = Arrays.copyOf(objectArray, objectArray.length, String[].class);
return stringArray;
}
}
Modified error messages:
Uncaught exception: uninitialized constant OpennlpTryer::ArrayStoreException
D:/BitNami/rubystack-1.9.3-12/projects/RjbTest/app/helpers/opennlp_tryer.rb:81:in `rescue in <class:OpennlpTryer>'
D:/BitNami/rubystack-1.9.3-12/projects/RjbTest/app/helpers/opennlp_tryer.rb:77:in `<class:OpennlpTryer>'
D:/BitNami/rubystack-1.9.3-12/projects/RjbTest/app/helpers/opennlp_tryer.rb:1:in `<top (required)>'
Revised error with Utils.java revised to "import java.lang.Object;":
Uncaught exception: uninitialized constant OpennlpTryer::ArrayStoreException
D:/BitNami/rubystack-1.9.3-12/projects/RjbTest/app/helpers/opennlp_tryer.rb:81:in `rescue in <class:OpennlpTryer>'
D:/BitNami/rubystack-1.9.3-12/projects/RjbTest/app/helpers/opennlp_tryer.rb:77:in `<class:OpennlpTryer>'
D:/BitNami/rubystack-1.9.3-12/projects/RjbTest/app/helpers/opennlp_tryer.rb:1:in `<top (required)>'
Rescue removed from OpennlpTryer shows error trapped in classes.rb:
Uncaught exception: uninitialized constant OpenNLP::POSTaggerME::ArrayStoreException
D:/BitNami/rubystack-1.9.3-12/ruby/lib/ruby/gems/1.9.1/gems/open-nlp-0.1.4/lib/open-nlp/classes.rb:16:in `rescue in tag'
D:/BitNami/rubystack-1.9.3-12/ruby/lib/ruby/gems/1.9.1/gems/open-nlp-0.1.4/lib/open-nlp/classes.rb:13:in `tag'
D:/BitNami/rubystack-1.9.3-12/projects/RjbTest/app/helpers/opennlp_tryer.rb:78:in `<class:OpennlpTryer>'
D:/BitNami/rubystack-1.9.3-12/projects/RjbTest/app/helpers/opennlp_tryer.rb:1:in `<top (required)>'
Same error but with all rescues removed so it's "native Ruby"
Uncaught exception: unknown exception
D:/BitNami/rubystack-1.9.3-12/ruby/lib/ruby/gems/1.9.1/gems/open-nlp-0.1.4/lib/open-nlp/classes.rb:15:in `method_missing'
D:/BitNami/rubystack-1.9.3-12/ruby/lib/ruby/gems/1.9.1/gems/open-nlp-0.1.4/lib/open-nlp/classes.rb:15:in `tag'
D:/BitNami/rubystack-1.9.3-12/projects/RjbTest/app/helpers/opennlp_tryer.rb:78:in `<class:OpennlpTryer>'
D:/BitNami/rubystack-1.9.3-12/projects/RjbTest/app/helpers/opennlp_tryer.rb:1:in `<top (required)>'
Revised Utils.java:
import java.util.Arrays;
import java.util.ArrayList;
import java.lang.String;
import opennlp.tools.postag.POSTagger;
import opennlp.tools.chunker.ChunkerME;
import opennlp.tools.namefind.NameFinderME; // interface instead?
import opennlp.tools.util.Span;
// javac -cp '.:opennlp.tools.jar' Utils.java
// jar cf utils.jar Utils.class
public class Utils {
public static String[] tagWithArrayList(
System.out.println("Tokens: ("+objectArray.getClass().getSimpleName()+"): \n"+objectArray);
POSTagger posTagger, ArrayList[] objectArray) {
return posTagger.tag(getStringArray(objectArray));
}
public static Object[] findWithArrayList(NameFinderME nameFinder, ArrayList[] tokens) {
return nameFinder.find(getStringArray(tokens));
}
public static Object[] chunkWithArrays(ChunkerME chunker, ArrayList[] tokens, ArrayList[] tags) {
return chunker.chunk(getStringArray(tokens), getStringArray(tags));
}
public static String[] getStringArray(ArrayList[] objectArray) {
String[] stringArray = Arrays.copyOf(objectArray, objectArray.length, String[].class);
return stringArray;
}
}
I ran cavaj on Utils.class that I unzipped from util.jar and this is what I found. It differs from Utils.java by quite a bit. Both come installed with the open-nlp 1.4.8 gem. I don't know if this is the root cause of the problem, but this file is the core of where it breaks and we have a major discrepancy. Which should we use?
import java.util.ArrayList;
import java.util.Arrays;
import opennlp.tools.chunker.ChunkerME;
import opennlp.tools.namefind.NameFinderME;
import opennlp.tools.postag.POSTagger;
public class Utils
{
public Utils()
{
}
public static String[] tagWithArrayList(POSTagger postagger, ArrayList aarraylist[])
{
return postagger.tag(getStringArray(aarraylist));
}
public static Object[] findWithArrayList(NameFinderME namefinderme, ArrayList aarraylist[])
{
return namefinderme.find(getStringArray(aarraylist));
}
public static Object[] chunkWithArrays(ChunkerME chunkerme, ArrayList aarraylist[], ArrayList aarraylist1[])
{
return chunkerme.chunk(getStringArray(aarraylist), getStringArray(aarraylist1));
}
public static String[] getStringArray(ArrayList aarraylist[])
{
String as[] = (String[])Arrays.copyOf(aarraylist, aarraylist.length, [Ljava/lang/String;);
return as;
}
}
Utils.java in use as of 10/07, compiled and compressed into utils.jar:
import java.util.Arrays;
import java.util.ArrayList;
import java.lang.String;
import opennlp.tools.postag.POSTagger;
import opennlp.tools.chunker.ChunkerME;
import opennlp.tools.namefind.NameFinderME; // interface instead?
import opennlp.tools.util.Span;
// javac -cp '.:opennlp.tools.jar' Utils.java
// jar cf utils.jar Utils.class
public class Utils {
public static String[] tagWithArrayList(POSTagger posTagger, ArrayList[] objectArray) {
return posTagger.tag(getStringArray(objectArray));
}
public static Object[] findWithArrayList(NameFinderME nameFinder, ArrayList[] tokens) {
return nameFinder.find(getStringArray(tokens));
}
public static Object[] chunkWithArrays(ChunkerME chunker, ArrayList[] tokens, ArrayList[] tags) {
return chunker.chunk(getStringArray(tokens), getStringArray(tags));
}
public static String[] getStringArray(ArrayList[] objectArray) {
String[] stringArray = Arrays.copyOf(objectArray, objectArray.length, String[].class);
return stringArray;
}
}
Failures are occurring in BindIt::Binding::load_klass in line 110 here:
# Private function to load classes.
# Doesn't check if initialized.
def load_klass(klass, base, name=nil)
base += '.' unless base == ''
fqcn = "#{base}#{klass}"
name ||= klass
if RUBY_PLATFORM =~ /java/
rb_class = java_import(fqcn)
if name != klass
if rb_class.is_a?(Array)
rb_class = rb_class.first
end
const_set(name.intern, rb_class)
end
else
rb_class = Rjb::import(fqcn) # <== This is line 110
const_set(name.intern, rb_class)
end
end
The messages are as follows, however they are inconsistent in terms of the particular method that is identified. Each run may display a different method, any of POSTagger, ChunkerME, or NameFinderME.
D:/BitNami/rubystack-1.9.3-12/ruby/lib/ruby/gems/1.9.1/gems/bind-it-0.2.7/lib/bind-it/binding.rb:110:in `import': opennlp/tools/namefind/NameFinderME (NoClassDefFoundError)
from D:/BitNami/rubystack-1.9.3-12/ruby/lib/ruby/gems/1.9.1/gems/bind-it-0.2.7/lib/bind-it/binding.rb:110:in `load_klass'
from D:/BitNami/rubystack-1.9.3-12/ruby/lib/ruby/gems/1.9.1/gems/bind-it-0.2.7/lib/bind-it/binding.rb:89:in `block in load_default_classes'
from D:/BitNami/rubystack-1.9.3-12/ruby/lib/ruby/gems/1.9.1/gems/bind-it-0.2.7/lib/bind-it/binding.rb:87:in `each'
from D:/BitNami/rubystack-1.9.3-12/ruby/lib/ruby/gems/1.9.1/gems/bind-it-0.2.7/lib/bind-it/binding.rb:87:in `load_default_classes'
from D:/BitNami/rubystack-1.9.3-12/ruby/lib/ruby/gems/1.9.1/gems/bind-it-0.2.7/lib/bind-it/binding.rb:56:in `bind'
from D:/BitNami/rubystack-1.9.3-12/ruby/lib/ruby/gems/1.9.1/gems/open-nlp-0.1.4/lib/open-nlp.rb:14:in `load'
from D:/BitNami/rubystack-1.9.3-12/projects/RjbTest/app/helpers/opennlp_tryer.rb:54:in `<class:OpennlpTryer>'
from D:/BitNami/rubystack-1.9.3-12/projects/RjbTest/app/helpers/opennlp_tryer.rb:1:in `<top (required)>'
from -e:1:in `load'
from -e:1:in `<main>'
The interesting point about these errors are that they are originating in OpennlpTryer line 54 which is:
OpenNLP.load
At this point, OpenNLP fires up RJB which uses BindIt to load the jars and classes. This is well before the errors that I was seeing at the beginning of this question. However, I can't help but think it is all related. I really don't understand the inconsistency of these errors at all.
I was able to add the logging function in to Utils.java, compile it after adding in an "import java.io.*" and compress it. However, I pulled it out because of these errors as I didn't know if or not it was involved. I don't think it was. However, because these errors are occurring during load, the method is never called anyway so logging there won't help...
For each of the other jars, the jar is loaded then each class is imported using RJB. Utils is handled differently and is specified as the "default". From what I can tell, Utils.class is executed to load its own classes?
Later update on 10/07:
Here is where I am, I think. First, I have some problem replacing Utils.java, as I described earlier today. That problem probably needs solved before I can install a fix.
Second, I now understand the difference between POSTagger and POSTaggerME because the ME means Maximum Entropy. The test code is trying to call POSTaggerME but it looks to me like Utils.java, as implemented, supports POSTagger. I tried changing the test code to call POSTagger, but it said it couldn't find an initializer. Looking at the source for each of these, and I am guessing here, I think that POSTagger exists for the sole purpose to support POSTaggerME which implements it.
The source is opennlp-tools file opennlp-tools-1.5.2-incubating-sources.jar.
What I don't get is the whole reason for Utils in the first place? Why aren't the jars/classes provided in bindings.rb enough? This feels like a bad monkeypatch. I mean, look what bindings.rb does in the first place:
# Default JARs to load.
self.default_jars = [
'jwnl-1.3.3.jar',
'opennlp-tools-1.5.2-incubating.jar',
'opennlp-maxent-3.0.2-incubating.jar',
'opennlp-uima-1.5.2-incubating.jar'
]
# Default namespace.
self.default_namespace = 'opennlp.tools'
# Default classes.
self.default_classes = [
# OpenNLP classes.
['AbstractBottomUpParser', 'opennlp.tools.parser'],
['DocumentCategorizerME', 'opennlp.tools.doccat'],
['ChunkerME', 'opennlp.tools.chunker'],
['DictionaryDetokenizer', 'opennlp.tools.tokenize'],
['NameFinderME', 'opennlp.tools.namefind'],
['Parser', 'opennlp.tools.parser.chunking'],
['Parse', 'opennlp.tools.parser'],
['ParserFactory', 'opennlp.tools.parser'],
['POSTaggerME', 'opennlp.tools.postag'],
['SentenceDetectorME', 'opennlp.tools.sentdetect'],
['SimpleTokenizer', 'opennlp.tools.tokenize'],
['Span', 'opennlp.tools.util'],
['TokenizerME', 'opennlp.tools.tokenize'],
# Generic Java classes.
['FileInputStream', 'java.io'],
['String', 'java.lang'],
['ArrayList', 'java.util']
]
# Add in Rjb workarounds.
unless RUBY_PLATFORM =~ /java/
self.default_jars << 'utils.jar'
self.default_classes << ['Utils', '']
end
SEE FULL CODE AT END FOR THE COMPLETE CORRECTED CLASSES.RB MODULE
I ran into the same problem today. I didn't quite understand why the Utils class were being used, so I modified the classes.rb file in the following way:
unless RUBY_PLATFORM =~ /java/
def tag(*args)
#proxy_inst.tag(args[0])
#OpenNLP::Bindings::Utils.tagWithArrayList(#proxy_inst, args[0])
end
end
In that way I can make the following test to pass:
sent = "The death of the poet was kept from his poems."
tokens = tokenizer.tokenize(sent).to_a
# => %w[The death of the poet was kept from his poems .]
tags = tagger.tag(tokens).to_a
# => ["prop", "prp", "n", "v-fin", "n", "adj", "prop", "v-fin", "n", "adj", "punc"]
R_G Edit:
I tested that change and it eliminated the error. I am going to have to do more testing to ensure the outcome is what should be expected. However, following that same pattern, I made the following changes in classes.rb as well:
def chunk(tokens, tags)
chunks = #proxy_inst.chunk(tokens, tags)
# chunks = OpenNLP::Bindings::Utils.chunkWithArrays(#proxy_inst, tokens,tags)
chunks.map { |c| c.to_s }
end
...
class OpenNLP::NameFinderME < OpenNLP::Base
unless RUBY_PLATFORM =~ /java/
def find(*args)
#proxy_inst.find(args[0])
# OpenNLP::Bindings::Utils.findWithArrayList(#proxy_inst, args[0])
end
end
end
This allowed the entire sample test to execute without failure. I will provide a later update regarding verification of the results.
FINAL EDIT AND UPDATED CLASSES.RB per Space Pope and R_G:
As it turns out, this answer was key to the desired solution. However, the results were inconsistent as it was corrected. We continued to drill down into it and implemented strong typing during the calls, as specified by RJB. This converts the call to use of the _invoke method where the parameters include the desired method, the strong type, and the additional parameters. Andre's recommendation was key to the solution, so kudos to him. Here is the complete module. It eliminates the need for the Utils.class that was attempting to make these calls but failing. We plan to issue a github pull request for the open-nlp gem to update this module:
require 'open-nlp/base'
class OpenNLP::SentenceDetectorME < OpenNLP::Base; end
class OpenNLP::SimpleTokenizer < OpenNLP::Base; end
class OpenNLP::TokenizerME < OpenNLP::Base; end
class OpenNLP::POSTaggerME < OpenNLP::Base
unless RUBY_PLATFORM =~ /java/
def tag(*args)
#proxy_inst._invoke("tag", "[Ljava.lang.String;", args[0])
end
end
end
class OpenNLP::ChunkerME < OpenNLP::Base
if RUBY_PLATFORM =~ /java/
def chunk(tokens, tags)
if !tokens.is_a?(Array)
tokens = tokens.to_a
tags = tags.to_a
end
tokens = tokens.to_java(:String)
tags = tags.to_java(:String)
#proxy_inst.chunk(tokens,tags).to_a
end
else
def chunk(tokens, tags)
chunks = #proxy_inst._invoke("chunk", "[Ljava.lang.String;[Ljava.lang.String;", tokens, tags)
chunks.map { |c| c.to_s }
end
end
end
class OpenNLP::Parser < OpenNLP::Base
def parse(text)
tokenizer = OpenNLP::TokenizerME.new
full_span = OpenNLP::Bindings::Span.new(0, text.size)
parse_obj = OpenNLP::Bindings::Parse.new(
text, full_span, "INC", 1, 0)
tokens = tokenizer.tokenize_pos(text)
tokens.each_with_index do |tok,i|
start, stop = tok.get_start, tok.get_end
token = text[start..stop-1]
span = OpenNLP::Bindings::Span.new(start, stop)
parse = OpenNLP::Bindings::Parse.new(text, span, "TK", 0, i)
parse_obj.insert(parse)
end
#proxy_inst.parse(parse_obj)
end
end
class OpenNLP::NameFinderME < OpenNLP::Base
unless RUBY_PLATFORM =~ /java/
def find(*args)
#proxy_inst._invoke("find", "[Ljava.lang.String;", args[0])
end
end
end
I don't think you're doing anything wrong at all. You're also not the only one with this problem. It looks like a bug in Utils. Creating an ArrayList[] in Java doesn't make much sense - it's technically legal, but it would be an array of ArrayLists, which a) is just plain odd and b) terrible practice with regard to Java generics, and c) won't cast properly to String[] like the author intends in getStringArray().
Given the way the utility's written and the fact that OpenNLP does, in fact, expect to receive a String[] as input for its tag() method, my best guess is that the original author meant to have Object[] where they have ArrayList[] in the Utils class.
Update
To output to a file in the root of your project directory, try adjusting the logging like this (I added another line for printing the contents of the input array):
try {
File log = new File("log.txt");
FileWriter fileWriter = new FileWriter(log);
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
bufferedWriter.write("Tokens ("+objectArray.getClass().getSimpleName()+"): \r\n"+objectArray.toString()+"\r\n");
bufferedWriter.write(Arrays.toString(objectArray));
bufferedWriter.close();
}
catch (Exception e) {
e.printStackTrace();
}

Categories

Resources