How to execute scala code using java - java

I am new to scala. I have a requirement to execute the scala class using java.
My exact requirement is: I need to pass the entire scala class (file) as an argument to the java jar. That jar should read the scala code and execute it. I have searched many sites but did not find the appropriate answer. Is there any way to do the same?
Thank you in Advance.

Besides of your motivation to do that, it is for sure possible (I did it using my IDE - sbt project)
I just made scala class as below:
import com.google.common.base.Objects
class Car(_color: String, _valid: Boolean) {
val color: String = _color
val valid: Boolean = _valid
override def toString = Objects.toStringHelper(this).add("color",color).add("valid", valid).toString
}
After that I made class with main method to test it.
public class Test {
public static void main(String[] args) {
Car test = new Car("test", true);
System.out.println("test = " + test);
}
}
It compiled without any problems and the result was like below:
test = Car{color=test, valid=true}

Scala has its own compiler scalac whereas java uses javac. Since scalac compiles to class file that java can read and assuming that you are only using java libraries in the class then you can load the class in java. So what you need is to call scalac to compile the scala file and then load the generate class file using ClassLoader

Related

Is there a way to run a Java Program when you don't know its name?

I'm making a game engine using LWJGL. The developer using it has to be able to use scripts. I decided to just make them use Java because writing an API in another language wasn't something I'm going to have the time nor experience to do. Anyways, I would have used x.main(); to run it, but The developer tells what the script is named, and that is stored in a variable. I just thought I could run a command to do that, using a method like exec() in python or eval() in JavaScript. I couldn't find a straightforward library that has this execution functionality.
To summarize this paragraph, I need a Java Library that can use a method like JavaScript's eval() or python's exec()
I dont know If I understood the problem, but I have focused on part of having "script name stored as variable" which sounds to me like a method name. You can invoke method by its name using reflections
public class MCAlu {
public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
String scriptName = "sayHello";
Method scriptMethod = MyScript.class.getMethod(scriptName);
scriptMethod.invoke(null, null);
}
}
class MyScript {
public static void sayHello() {
System.out.println("Hi there!");
}
}
Since class has to be known and on the classpath (unless you will load it in the runtime), class name can be as well provided as string resulting in
String scriptClass="MyScript";
String scriptName = "sayHello";
Method scriptMethod = Class.forName(scriptClass).getMethod(scriptName);
scriptMethod.invoke(null, null);
One (quite popular) tool that can help you run Java sources as scripts is JBang. Java programs have to be compiled (to Java class files) to be able to run by a JVM. So, basically, JBang hides this compilation step and invokes the JVM with our compiled class.

.dll file integration in java eclipse

I am having a .dll file which has a wrapper in C,C++, .Net and python, but not in Java. I am successful in loading the .dll file using following code in my Java
public class
public static void main(String[] {
// print when the program starts
System.out.println("Program starting...");
System.out.println("Loading Library...");
Runtime.getRuntime().loadLibrary("HelloJava");
System.out.println("Library Loaded.");
}
}
which gives the following output:
Now my question is that if this file is loaded, How do I access it's functions to use in my Java workspace?
Since it is the C-DLL, so How should I fetch the module values from this .dll.
Note:
I have made a folder named dll under my Java project path from where I loaded the library in the above code.
I browsed for the concept for JNA and JNI but lacked the understanding concept, that's why posted the question.
Thanks in advance.
I think you need to know the methods in your DLL first. I really don't know how to list the methods using JNA or JNI, but you have to know the method's signature before starting, maybe from a documentation, because you normally can find the DLL's documentation on the web, or you even can use a Reflector (like red-gate) to find out your methods.
Then:
Download the JNA .jar file and add it to your build in your Java project.
Put the .dll in the root directory of your Java project.
Create an Interface that contains the functions from the dll that you want to use.
For example, lets say your HelloWorld DLL has a String hello(String hey) method in C++, then in your Java project you will have to do something like:
import com.sun.jna.Library;
import com.sun.jna.Native;
public class Main {
public interface Ihello extends Library {
public String hello(String hey);
}
public static void main(String args[]) {
//"hello-world is the name my DLL, for example.
Hello h = Native.load("hello-world", Hello.class);
System.out.println(h.hello(" John! ");
}
}
Here is a good example, regards.

Accessing Kotlin Sealed Class from Java

Up until now I have been using this Kotlin sealed class:
sealed class ScanAction {
class Continue: ScanAction()
class Stop: ScanAction()
... /* There's more but that's not super important */
}
Which has been working great in both my Kotlin and Java code. Today I tried changing this class to use objects instead (as is recommended to reduce extra class instantiation):
sealed class ScanAction {
object Continue: ScanAction()
object Stop: ScanAction()
}
I am able to reference this easy peasy in my other Kotlin files, but I am now struggling to use it in my Java files.
I have tried the following and both of these kick back compilation errors when trying to make reference to in Java:
ScanAction test = ScanAction.Continue;
ScanAction test = new ScanAction.Continue();
Does anyone know how I can reference the instance in Java now?
You have to use the INSTANCE property:
ScanAction test = ScanAction.Continue.INSTANCE;

Groovy #Immutable classes in Java

I often recommend Groovy's #Immutable AST transformation as an easy way to make classes, well, immutable. This always works fine with other Groovy classes, but someone recently asked me if I could mix those classes into Java code. I always thought the answer was yes, but I'm hitting a snag.
Say I have an immutable User class:
import groovy.transform.Immutable
#Immutable
class User {
int id
String name
}
If I test this using a JUnit test written in Groovy, everything works as expected:
import org.junit.Test
class UserGroovyTest {
#Test
void testMapConstructor() {
assert new User(name: 'name', id: 3)
}
#Test
void testTupleConstructor() {
assert new User(3, 'name')
}
#Test
void testDefaultConstructor() {
assert new User()
}
#Test(expected = ReadOnlyPropertyException)
void testImmutableName() {
User u = new User(id: 3, name: 'name')
u.name = 'other'
}
}
I can do the same with a JUnit test written in Java:
import static org.junit.Assert.*;
import org.junit.Test;
public class UserJavaTest {
#Test
public void testDefaultCtor() {
assertNotNull(new User());
}
#Test
public void testTupleCtor() {
assertNotNull(new User(3, "name"));
}
#Test
public void testImmutableName() {
User u = new User(3, "name");
// u.setName("other") // Method not found; doesn't compile
}
}
This works, though there are troubles on the horizon. IntelliJ 15 doesn't like the call to new User(), claiming that constructor is not found. That also means the IDE underlines the class in red, meaning it has a compilation error. The test passes anyway, which is a bit strange, but so be it.
If I try to use the User class in Java code directly, things start getting weird.
public class UserDemo {
public static void main(String[] args) {
User user = new User();
System.out.println(user);
}
}
Again IntelliJ isn't happy, but compiles and runs. The output is, of all things:
User(0)
That's odd, because although the #Immutable transform does generate a toString method, I rather expected the output to show both properties. Still, that could be because the name property is null, so it's not included in the output.
If I try to use the tuple constructor:
public class UserDemo {
public static void main(String[] args) {
User user = new User(3, "name");
System.out.println(user);
}
}
I get
User(0, name)
as the output, at least this time (sometimes it doesn't work at all).
Then I added a Gradle build file. If I put the Groovy classes under src\main\groovy and the Java classes under src\main\java (same for the tests but using the test folder instead), I immediately get a compilation issue:
> gradle test
error: cannot find symbol
User user = new User(...)
^
I usually fix cross-compilation issues like this by trying to use the Groovy compiler for everything. If I put both classes under src\main\java, nothing changes, which isn't a big surprise. But if I put both classes under src\main\groovy, then I get this during the compileGroovy phase:
> gradle clean test
error: constructor in class User cannot be applied to the given types;
User user = new User(3, "name");
required: no arguments
found: int,String
reason: actual and formal arguments differ in length
Huh. This time it's objecting to the tuple constructor, because it thinks it only has a default constructor. I know the transform adds a default, a map-based, and a tuple constructor, but maybe they're not being generated in time for the Java code to see them.
Incidentally, if I separate the Java and Groovy classes again, and add the following to my Gradle build:
sourceSets {
main {
java { srcDirs = []}
groovy { srcDir 'src/main/java' }
}
}
I get the same error. If I don't add the sourceSets block, I get the User class not found error from earlier.
So the bottom line is, what's the correct way to add an #Immutable Groovy class to an existing Java system? Is there some way to get the constructors to be generated in time for Java to see them?
I've been making Groovy presentations to Java developers for years and saying you can do this, only to now run into problems. Please help me save face somehow. :)
I did try your scenario as well, where you have a single project with a src/main/java and a src/main/groovy directory and ended up with compilation errors similar to what you saw.
I was able to use Groovy immutable objects in Java when I put the Groovy immutables in a separate project from the Java code. I have created a simple example and pushed it to GitHub (https://github.com/cjstehno/immut).
Basically it's a Gradle multi-project with all the Groovy code (the immutable object) in the immut-groovy sub-project and all the Java code in the immut-java project. The immut-java project depends on the immut-groovy project and uses the immutable Something object:
public class SomethingFactory {
Something createSomething(int id, String label){
return new Something(id, label);
}
}
I added a unit test in the Java project which creates a new instance of the immutable Groovy class and verifies its contents.
public class SomethingFactoryTest {
#Test
public void createSomething(){
Something something = new SomethingFactory().createSomething(42, "wonderful");
assertEquals(something.getId(), 42);
assertEquals(something.getLabel(), "wonderful");
}
}
This is not really ideal, but it works.

Create API in Groovy for Java

I'm need to create an api for what will be a suite of primarily java applications. I need to do this quickly however, and at the moment I'm most comfortable writing in groovy. My question is, can I create this api in groovy, and use it in java applications without any special hoops?
That is, can I create a jar from my groovy classes and methods, and have the java applications use this jar as though it were created in java?
Yes, you can. Just compile using gradle, ant, whatever, to generate a jar. The resulting jar will depend on Groovy runtime jar and modules, if any. Groovy compiles to bytecode, so Java doesn't really know the differente. Only dynamic stuff won't work.
MyLib.groovy:
class MyLib {
def string
MyLib(string) {
this.string = string
}
String yell() {
string.toUpperCase() + "!!!"
}
}
Compiled:
$ groovyc MyLib.groovy
Writing the Java class which uses the Groovy one, TestMyLib.java:
public class TestMyLib {
public static void main(String[] args ) {
MyLib my = new MyLib("john doe");
System.out.println(my.yell()); // prints JOHN DOE!!!
}
}
Compiling:
$ javac TestMyLib.java
And execution:
$ java -cp $GROOVY_HOME/embeddable/groovy-all-2.1.8.jar:. TestMyLib
JOHN DOE!!!

Categories