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!!!
Related
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.
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
I have been trying to compile one perticular class of my project with a higher compiler compliance level than the rest of the project but i cant figure out how to do it.
I am compiling the project in Java 6 (for compatibility reasons) and there is a single class which requires Java 8 and will only be instantiated in the code (With reflection) if the version of Java it is running on is >=8.
The problem is that the class which is in Java 8 obviously does not compile in Java 6 so i would like to ask, if there is a way in Eclipse to compile this single class with Java 8 when the project is exported to a Runnable Jar.
There is always the option of compiling the project in Java 6 (without the java 8 class), exporting, and manually compiling that class with Java 8 and then inserting in to the Jar file manually which works fine but is not very convenient.
For example lets suppose that the project consists of the following:
A Common Interface:
public interface CommonInterface {
public void foo();
}
A Java 8 class:
public class Java8Class implements CommonInterface {
#Override
public void foo() {
Arrays.asList("Some", "Java", "8", "code").forEach(System.out::println);
}
}
A Java 6+ class:
public class Java6PlusClass implements CommonInterface {
#Override
public void foo() {
List<String> list = Arrays.asList("Some", "Java", "6", "code");
for (String s : list) {
System.out.println(s);
}
}
}
And the main program class:
public class Selector {
public static void main(String[] args) throws ReflectiveOperationException{
CommonInterface ci = getCorrectInstance();
ci.foo();
}
private static CommonInterface getCorrectInstance() throws ReflectiveOperationException {
String version = System.getProperty("java.version");
Matcher m = Pattern.compile("\\d\\.(\\d)\\..+").matcher(version);
String clazz = null;
if (m.find()) {
int jv = Integer.parseInt(m.group(1));
if (jv == 8)
clazz = "Java8Class";
else if (jv >= 6)
clazz = "Java6PlusClass";
}
if (clazz == null)
return null;
return (CommonInterface) Class.forName(clazz).newInstance();
}
}
In the above example, is it possible to configure Eclipse such that all classes apart from "Java8Class" compile with Java 6 compliance and the "Java8Class" compiles with Java 8 compliance?
Thanks.
You cannot do this in Eclipse, and I don't believe what you are trying to achieve is a good idea.
Here's what you could do instead:
Change the code of this Java 8 class to something equivalent in Java 6 (if possible).
Create a new project with this single class, and compile it with Java 8 compliance level. Specify this new jar file on the command line when launching your application, and it should do the trick.
Have 2 different versions of your application (one that is Java 8 compliant, and the other being Java 6 compliant), and launch the correct one based on the Java version available on the system.
I'm not totally sure if that second option would work simply by putting the jar file in the classpath in the cases where your program is executed using a Java 6 JRE. You might have to do some class loader trickery if it fails to start.
I'm trying to run ajc compiler from Java (not from Maven or Ant!). The question is which Maven dependency do I need and which class is an entry point? The best option I have now is org.aspectj.tools.ajc.Main from org.aspectj:aspectjtools:1.7.2. Am I right?
Yes. In your Java project you need aspectjrt.jar (for the runtime) and aspectjtools.jar (for the compiler) on the class path. Then you can build an AspectJ project and create a JAR file containing aspects and classes like this:
import org.aspectj.tools.ajc.Main;
public class AjcRunner {
public static void main(String[] args) throws Exception {
String[] ajcArgs = {
"-sourceroots", "c:\\my\\aspectj_project\\src",
"-outjar", "my_aspects.jar"
};
Main.main(ajcArgs);
}
}
Afterwards you can test the result on the console like this, assuming you have a class Application with a main method:
java -cp C:\path\to\aspectjrt.jar;my_aspects.jar Application
I have a library which is written in C++ (actually a Firefox plugin, xyz.dll) and I need to access its methods from Java.
public class AccessLibrary {
public interface Kernel32 extends Library {
public void showVersion();
}
public static void main(String[] args) {
Kernel32 lib = (Kernel32) Native.loadLibrary("xyz.dll", Kernel32.class);
lib.showVersion();
}
}
While executing got the following error:
java -jar dist/accessLibrary.jar
Exception in thread "main" java.lang.UnsatisfiedLinkError: Error looking up function 'showVersion': The specified procedure could not be found.
In the native library source code, the method is defined like this
void CPlugin::showVersion() {
/* ... */
}
I am very new to Java. May be I am missing something basic. Looked into similar questions but none of them solves my problem.
Forgot to mention I am using Windows 7 64bit and Java 7.
First, you cannot export a class method and load it into java. The name will get mangled, and java wouldn't know how to call it properly. What you need to do is break it out into a separate function on its own.
After that:
As already pointed out, make sure you export the function. You can export using one of two ways. The first is what is mentioned, which is to use __declspec( dllexport ). The second is to put it into the def file.
Additionally, make sure you mark it as extern "C" otherwise the name will get mangled. All the details are here: Exporting functions from a DLL with dllexport
So the the signature should be something like this:
extern "C" __declspec(dllexport) void showVersion () {
}
Finally, the depends tool can be downloaded here: http://www.dependencywalker.com/
I think your native library needs to provide a C-style interface, for example
__declspec( dllexport ) void showVersion() {
/* ... */
}
Ideally, take a look at your DLL with depends.exe (which is available through the Windows SDK), there you'll see if your DLL provides the correct function exports.