Script engine giving error when evaluating Scala script in Java - java

I have a app that executes scala scripts that get passed to it. The following is an example of how I am attempting to execute the scala code.
String script = "println(\"Hello World!\")";
ScriptEngine scriptEngine = new ScriptEngineManager().getEngineByName("scala");
scriptEngine.eval(script);
I get the following error.
[init] error: error while loading Object, Missing dependency 'object scala in compiler mirror', required by /Library/Java/JavaVirtualMachines/jdk1.7.0_80.jdk/Contents/Home/jre/lib/rt.jar(java/lang/Object.class)
Failed to initialize compiler: object scala in compiler mirror not found.
** Note that as of 2.8 scala does not assume use of the java classpath.
** For the old behavior pass -usejavacp to scala, or if using a Settings
** object programmatically, settings.usejavacp.value = true.
I am using Java 7 (jdk1.7.0_80.jdk) on a Mac. I am running this from within a spring-boot app.
Scala maven dependency used.
<dependency>
<groupId>org.apache.clerezza.scala</groupId>
<artifactId>script-engine</artifactId>
<version>1.0.0</version>
</dependency>
Why am I getting this error?

We need to import and initialize the script engine like this:
import javax.script.*;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
public class TestScript {
public static void main(String... args) throws Exception {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("scala");
...
With ScriptEngineManager().getEngineByName("scala") a matching script engine is looked up. This just gives us the engine but not the required libraries and hooks to really execute a script.
There is one thing to note about the way Scala loads the required standard classes for the JVM. In case of the execution of scala standard Scala libraries are placed in the classpath of the JVM. This would not be the case here. You can read this for a reference. Trying to run a sample class would result in the following exception:
reflect.jar:. TestScript
[init] error: error while loading Object, Missing dependency 'object scala in compiler mirror', required by /Library/Java/JavaVirtualMachines/jdk1.8.0_65.jdk/Contents/Home/jre/lib/rt.jar(java/lang/Object.class)
Failed to initialize compiler: object scala in compiler mirror not found.
** Note that as of 2.8 scala does not assume use of the java classpath.
** For the old behavior pass -usejavacp to scala, or if using a Settings
** object programmatically, settings.usejavacp.value = true.
Exception in thread "main" scala.reflect.internal.MissingRequirementError: object scala in compiler mirror not found.
We can work around this by using the scala java tools helping us to load the standard Scala libraries into the JVM classpath. This is one way to make our Scala script work:
import javax.script.*;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import scala.tools.nsc.interpreter.IMain;
import scala.tools.nsc.settings.MutableSettings.BooleanSetting;
public class TestScript {
public static void main(String... args) throws Exception {
....
((BooleanSetting)(((IMain)engine).settings()
.usejavacp())).value_$eq(true);
....
The other is to simply execute the code with the following option:
$ java -Dscala.usejavacp=true ...
The complete script is this:
import javax.script.*;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import scala.tools.nsc.interpreter.IMain;
import scala.tools.nsc.settings.MutableSettings.BooleanSetting;
public class TestScript {
public static void main(String... args) throws Exception {
ScriptEngine engine = new ScriptEngineManager().getEngineByName("scala");
((BooleanSetting)(((IMain)engine)
.settings().usejavacp()))
.value_$eq(true);
String testScript = "var a:Int = 10";
engine.eval(testScript);
String testScript2 = "println(a)";
engine.eval(testScript2);
String testScript3 = "println(a+5)";
engine.eval(testScript3);
}
}
Compiling and running this is pretty straight forward as we need the Scala libraries in the classpath.
Compiling:
$ javac -cp /Users//hkropp/bin/scala-2.11.7/lib/scala-library.jar:\
/Users//hkropp/bin/scala-2.11.7/lib/scala-compiler.jar:\
/Users//hkropp/bin/scala-2.11.7/lib/scala-reflect.jar \
TestScript.java
Running:
$ java -Dscala.usejavacp=true \-cp /Users//hkropp/bin/scala-2.11.7/lib/scala-library.jar:\
/Users//hkropp/bin/scala-2.11.7/lib/scala-compiler.jar:\
/Users//hkropp/bin/scala-2.11.7/lib/scala-reflect.jar:. \
TestScript
10
15

Related

java.lang.UnsatisfiedLinkError: Error looking up function

I'm trying to utilize a .dll written in visual basic. I didn't write it so don't have the source code to it. I can load it ok and display the methods inside, but get "java.lang.UnsatisfiedLinkError: Error looking up function" when trying to call one. Here is my code:
package dlltest;
import com.sun.jna.Library;
import com.sun.jna.Native;
import java.lang.reflect.Method;
import java.util.Collection;
public class DllTest {
public interface TC2005 extends Library {
public boolean TCEnabled();
}
public static void main(String[] args) {
TC2005 tc2005 = (TC2005)Native.loadLibrary("TC2000Dev",TC2005.class);
Method[] methods = tc2005.getClass().getDeclaredMethods();
for (Method method:methods) System.out.println(method);
System.out.println("TCEnabled="+tc2005.TCEnabled());
}
}
Here is the output:
public final boolean com.sun.proxy.$Proxy0.TCEnabled()
Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'TCEnabled': The specified procedure could not be found.
at com.sun.jna.Function.<init>(Function.java:179)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:345)
at com.sun.jna.NativeLibrary.getFunction(NativeLibrary.java:325)
at com.sun.jna.Library$Handler.invoke(Library.java:203)
at com.sun.proxy.$Proxy0.TCEnabled(Unknown Source)
at dlltest.DllTest.main(DllTest.java:70)
There are many more functions and output but just showing one for clarity.
Been reading posts on the subject all day with no joy. Some talk about compilers mangling the method names and hence need for a FunctionMapper code. To get the real method names everyone says to use Dependency Walker. Tried using that to load the .dll Lots of errors. Also tried loading a .exe that uses the .dll and then running the Profiler option in DW. That locks up the program. (Not Responding).
Suggestions?
Cross check your version. You need function which is not present in loaded .dll . Such cases can be seen with incorrect version.

How to import a function from a Java classes static method drools 6.5

I'm having trouble getting the function importing to work from Java class to drools DRL. For example with the following DRL:
package rules
import com.company.my.Person;
import function com.company.my.FunctionUtility.allowVote;
dialect "java"
ruleflow-group "PersonRules"
rule "person can vote"
when
$p:Person(age > 17)
then
allowVote();
end
referencing imported Java Function:
public class FunctionUtility {
public static void allowVote(){
System.out.println("Voting allowed");
}
}
I'm getting the following error when doing mvn clean install:
The method allowVote() is undefined for the type Rule_Person_Can_Vote
Only a type can be imported. com.company.my.FunctionUtility.allowVote resolves to a package
This stackoverflow question had a similar ask, but their solution is not consistent with the drools documentation or this 6.5.0 unit test for importing functions and doesn't work for me in any case.
Has anyone gotten function imports to work with drools 6.x, and if so how did you do it?

Exception during run ready code

When I imported written code using Eclipse and run it as java application, I get an Exception during run ready code
This is the error...
Exception in thread "main" java.lang.NoSuchMethodError: backtype.storm.topology.TopologyBuilder.setBolt(Ljava/lang/String;Lbacktype/storm/ topology/IBasicBolt;Ljava/lang/Integer;)Lbacktype/storm/topology/BoltDeclarer;
at TopologyMain.main(TopologyMain.java:18)
Code is
import spouts.WordReader;
import backtype.storm.Config;
import backtype.storm.LocalCluster;
import backtype.storm.topology.TopologyBuilder;
import backtype.storm.tuple.Fields;
import bolts.WordCounter; import bolts.WordNormalizer;
public class TopologyMain { public static void main(String[] args) throws InterruptedException {
//Topology definition
TopologyBuilder builder = new TopologyBuilder();
builder.setSpout("word-reader",new WordReader());
builder.setBolt("word-normalizer", new WordNormalizer()).shuffleGrouping("word-reader");
builder.setBolt("word-counter", new WordCounter(),1).fieldsGrouping("word- normalizer", new Fields("word"));
//Configuration
Config conf = new Config();
conf.put("wordsFile", args[0]); onf.setDebug(false);
//Topology run
conf.put(Config.TOPOLOGY_MAX_SPOUT_PENDING, 1);
LocalCluster cluster = new LocalCluster();
cluster.submitTopology("Getting-Started-Toplogie", conf, builder.createTopology());
Thread.sleep(1000); cluster.shutdown();
}
}
Probably you've modified your TopologyBuilder class or JAR having that class. Because that kind of error implies that your compile-time and run-time versions of classes are not the same, i.e. the .class has been somehow modified after you compiled your program. Particularly, the program was compiled with setBolt() method, and after that, the method was removed, renamed or modified within .class
The program and method arguments that you are passing as builder.setBolt("word-counter", new WordCounter(),1).fields...() is correct. The method signature builder.setBolt(String id, IBasicBolt bolt, Number parallelism_hint) should accept the parameters that you are passing as long as the JDK version set is 1.5 or above.
Starting from the Java version 1.5 Autoboxing feature, the imported .class or compiled class should resolve the references from primitive int to java.lang.Integer to java.lang.Number as java.lang.Number is super class.
The main issue could be the JDK version 1.4 or less set in your project or workspace settings. Changing the JDK version to 1.5 or above should resolve the issue.
add following maven dependency
<dependency>
<groupId>storm</groupId>
<artifactId>storm</artifactId>
<version>0.8.2</version>
</dependency>

Scala Import and Packages error

I want to import and call a java class(which in from an external package ) from a scala object . My code is like this
Java code:
package com.test.services.account;
public class MyMain {
public static void main(String[] args) {
System.out.println("coming into main");
}
}
Scala code:
package com.newtest.newservice.scala
import _root_.com.test.services.account.MyMain
object scalatest {
def main(args: Array[String]) {
println("Hello, world! " + args.toList)
// Deployer.main(args)
val de:MyMain = new MyMain()
println(de.toString())
}
}
when i compile it using scalac scalatest.scala, it gives an error
scalatest.scala:2: error: object test is not a member of package com
import root.com.test.services.account.MyMain
^
one error found
Could anybody guide me how can i import my java class into scala code ?
Thanks
Suresh
If you don't want to use something like sbt, you should first decide where your CLASSPATH is. Since you have two different class files (one generated from Java and one from Scala), you need at least one directory where your class files need to live. Let's say that is d:\myclasses.
In that case, you'd compile the java file using this command:
d:\mycode> javac -d d:\myclasses MyMain.java
This would generate your Java class file in the appropriate package structure at d:\myclasses. Then you would compile the scala file like so
scalac -classpath d:\myclasses -d d:\myclasses scalatest.scala
Instead of passing the classpath as part of the scalac command line, you could also set your CLASSPATH environment variable to d:\myclasses.

java command line errors

I'm new to java and I'm trying to compile and run a web service example from a book.
The example uses 3 files.
I can create an Eclipse Project and Run it. It works fine this way.
From the command line I tried
javac TimeServer.java TimeServerImpl.java TimeServerPublisher.java
And got no errors
This program does not run on the command line returns error:
"Could not find the main class"
java TimeServerPublisher
running using the -classpath option returns the same result.
Set classpath does not help either. ie
java -classpath . TimeServerPublisher
fails as well
Most of the online docs specify I need a classpath. I tried everything they suggested.
Please Help. Thanks in advance
Source:
TimeServer.java
package ch01.ts;
import javax.jws.WebService;
import javax.jws.WebMethod;
import javax.jws.soap.SOAPBinding;
import javax.jws.soap.SOAPBinding.Style;
#WebService
#SOAPBinding(style = Style.RPC) // more on this later
public interface TimeServer
{
#WebMethod String getTimeAsString();
#WebMethod long getTimeAsElapsed();
}
TimeServerImpl.java
package ch01.ts;
import java.util.Date;
import javax.jws.WebService;
#WebService(endpointInterface = "ch01.ts.TimeServer")
public class TimeServerImpl implements TimeServer
{
#Override
public String getTimeAsString()
{
return new Date().toString();
}
#Override
public long getTimeAsElapsed()
{
return new Date().getTime();
}
TimeServerPublisher.java
package ch01.ts;
import javax.xml.ws.Endpoint;
public class TimeServerPublisher
{
public static void main(String[ ] args)
{
Endpoint.publish("http://127.0.0.1:9876/ts", new TimeServerImpl());
}
}
Your class is not named TimeServerPublisher; it's named ch01.ts.TimeServerPublisher. Even if you manage to get the JVM to find your class file, it will reject it with a wrong-name error, as you must invoke the class with its full name.
Put all the class files into a directory ch01/ts if they're not there already, and from ch01's parent directory, type
java -cp . ch01.ts.TimeServerPublisher
I guarantee that done correctly this will work.
get rid of the package statements until you know how they work. to have that package, your sources and binaries should be under ./ch01/ts/ and you would compile and invoke as:
javac ch01/ts/*.java
java ch01.ts.TimeServerPublisher
Move all your class files to folder ch01/ts.
and then execute command
java ch01.ts.TimeServerPublisher
There you go. If you say javac -d ch01/ts *.java during compilation, it will be solved.

Categories

Resources