I have a javascript function (very big one!) that I need its functionality in a Java (Groovy) class. It is a simple calendar converter. I can rewrite it in groovy but just want to know if it is possible to call javascript function from a java (groovy) method? I guess functional testing libraries like selenium and Canoo should have something like this, am I right?
PS: I don't want to wake up a real-world browser in order to use its JS runtime env.
Thanks,
As mentioned in the other answers, it is possible to use the Scripting API provided as part of the javax.script package, available from Java 6.
The following is a Groovy example which executes a little bit of Javascript:
import javax.script.*
manager = new ScriptEngineManager()
engine = manager.getEngineByName("JavaScript")
javascriptString = """
obj = {"value" : 42}
print(obj["value"])
"""
engine.eval(javascriptString) // prints 42
It is not necessary to call a browser to execute Javascript when using the Scripting API, but one should keep in mind that browser-specific features (probably the DOM-related functionalities) will not be available.
You can use Rhino, an implementation of JavaScript language in Java. Here is example of calling JavaScript function from java, but you can do it from groovy also.
Related
I am using Gatling for the first time. I have functional tests that are written in java/cucumber. I want to run these functional tests from a Gatling-scala script to do the performance testing of my application. Is there any way to do so?
The idea is to use the existing functional tests and wrap them around gatling scripts so that they could be executed concurrently for multiple users.
What you want to do is to call a Java method from Scala.
Make sure that the method you want to call is available on the class path Scala sees. Then refer to the method you want to call.
This blog post may help you.
If you are using the Gatling for the first time, have you been considering usage of some other performance tools which can provide you such options? As an analog to Gatling for your case (if you want to create functional tests on Java) and run them later using loading tools I would recommend you to check the Locust.
Using Locust you can write the tests using Java or even Kotlin. You can find the handy tutorial by this link:
https://www.blazemeter.com/blog/locust-performance-testing-using-java-and-kotlin
Another preferable option might be to use Taurus framework which allows you to run JUnit/TestNG tests right away:
https://gettaurus.org/docs/JUnit/
https://www.blazemeter.com/blog/navigating-your-first-steps-using-taurus
Gatling is primarily for http testing. what I would do is to call java code from within a gatling test that will return me a value that I check for ex: I return a boolean from a java code below for doing performance test(same also for functional test which needs extending GatlingHttpFunSpec instead of Simulation class). Also will need to use a dummy endpoint (like a health check url which will always return 200).
val myJavaTest: MyJavaTest = new MyJavaTest()
val baseURL="http://localhost:8080"
val endpoint_headers=Map("header1" -> "val1")
val endPoint="/myurl/healthcheck"
setUp(scenario("Scenario ")
.exec(
http("run first test")
.get(endpoint)
.headers(endpoint_headers)
.check(bodyString.transform(str => {
myJavaTest.runTest1()//should return boolean
}).is(true)))
.inject(atOnceUsers(1))).protocols(http
.baseURL(baseURL))
I'm using the example listed here:
http://www.luaj.org/luaj/3.0/README.html#5
It works fine, but instead of using inside the Lua script:
require 'hyperbolic'
I would like to use this or something similar in the java code
_G.set("hyperbolic", new hyperbolic());
Mostly to pass initial arguments to hyperbolic (like new hyperbolic(2.4, 1.67) when initializing it, so the Lua script is simple and "kid" friendly.
Any ideas or suggestions? Google isn't helping, possibly because I'm searching for the wrong thing..
By convention, instances of Java classes that implement lua libraries need to be called once with arguments (modulename, environment), and they set up the library for the supplied environment.
As coded, the hyperbolic library ignores the module name, and puts its functions in globals.hyperbolic
Globals globals = JsePlatform.standardGlobals();
hyperbolic module = new hyperbolic();
module.call(LuaValue.valueOf("hyperbolic"), globals);
This loads the library so you can use the function from scripts that have those globals as their environment. For example,
LuaValue chunk = globals.load(
"print( 'sinh(0.5)', hyperbolic.sinh(0.5) )");
chunk.call();
will then output
sinh(0.5) 0.5210953
Unlike require(), this example does not populate the package.loaded table, so if you go on to require('hyperbolic'), it may be loaded a second time.
I am investigating methods of dynamically modifying the behaviour of a Java application (specifically, I'm trying to make a Minecraft mod that allows users to modify the behaviour of the objects they find by writing code without the need to restart the game) and I stumbled upon Groovy. My question is: is it possible to integrate Java and Groovy in such way they "share" objects? (I'm thinking about having a specific set of classes that are actually Groovy code so you can change the code during runtime, similarly to what you can do in any Smalltalk implementation)
Take a look at Integrating Groovy in a Java Application. It shows examples of how you can run a Groovy script from inside a Java application and share data between them using groovy.lang.Binding.
What a cool idea!
1. Groovy: Java and Groovy can share objects and call back and forth. Groovy classes that implement Java interfaces are easily called from Java. (There are other ways, like calling groovyObject.invokeMethod("methodName", args) from Java.) Of JVM languages, Groovy has the tightest integration with Java. It's also easy for Java programmers to learn since it shares so much with Java.
The book Groovy in Action has a chapter on "Integrating Groovy" that explains and compares the approaches (in more detail than the reference docs do): GroovyShell, GroovyScriptEngine, GroovyClassLoader, Spring integration, and JSR-223 ScriptEngineManager. GroovyClassLoader is the most capable choice.
However, while it's easy to compile and load Groovy code at runtime, I'm puzzled about how to change behavior of existing object instances (short of the notes below on hot swapping). (It might depend on whether the class overrides a Java interface or subclasses a Java class.) Consider:
class G implements Runnable {
void run() { println 'Groovy' }
}
g = new G()
g.run()
This prints Groovy. Now redefine the class:
class G implements Runnable {
void run() { println 'Groovy!' }
}
g1 = new G()
g.run()
g1.run()
This prints
Groovy
Groovy!
Now use the meta-class to change methods at runtime:
G.metaClass.run = { println 'Groovy!!!' }
g2 = new G()
g.run()
g1.run()
g2.run()
This prints
Groovy
Groovy!
Groovy!
If we omitted implements Runnable from those class definitions, then the last step would instead print
Groovy
Groovy!
Groovy!!!
But with our class that does implement Runnable, now do:
G.metaClass.run = { println 'Very Groovy!!!' }
g3 = new G()
g.run()
g1.run()
g2.run()
g3.run()
this prints:
Groovy
Groovy!
Very Groovy!!!
Very Groovy!!!
A workaround would implement the methods in closures held in class variables.
2. Hot Swapping: If the main point is to redefine method bodies at run time for classes with existing instances, then you can simply run within an IDE's debugger and use hot swapping.
E.g. for IntelliJ, here are the instructions to configure hot swapping of Java and Groovy code.
3. Expanded Hot Swapping: If you also want to be able to add/remove methods and instance variables at run time, then see this JetBrains article on extended hot swapping via DCEVM (Dynamic Code Evolution VM).
See Hot Swap code code at https://github.com/HotswapProjects
Also see this SO Q&A on hot swapping techniques.
I'm not sure that's something you can accomplish with Groovy without compiling it. You could do it, but the "scripting" aspect of Groovy won't help you. I'd look into having the player write javascript and using Java's ScriptEngine. See here: http://docs.oracle.com/javase/7/docs/technotes/guides/scripting/programmer_guide/
Yes, You can achieve that. For example, You have something written in java that uses some objects from let's say spring context. So now what u can do is :
execute groovy script before that java code is executed,
use delegate design pattern to wrap it, overwrite some methods
finaly put it back into context.
So basicly in moment where Your java code is executed, he'll get a wrapped object with some changes made in runtime.
If that's what are You trying to do, let me know i could write You some example code.
I am using SmartGWT and I wish to access com.smartgwt.client.Version from JavaScript. In Firefox's Web Console, I have tried:
frames[0].$entry(Lcom_smartgwt_client_Version::getVersion()));
and
frames[0].$entry(#com.smartgwt.client.Version.getVersion());
and
frames[0].$entry(#com.smartgwt.client.Version::getVersion());
and
frames[0].$entry(#com.smartgwt.client.Version::getVersion()());
But all of them return a syntax error.
SmartGWT is deployed with my WAR and I can see other SmartGWT classes listed when I do just frames[0].
What is the right syntax to call this static Java method?
Those JSNI references do not work except in JSNI code in your java files. References to Java methods and fields in JSNI are not actually valid JavaScript, but part of the JSNI language to enable those native methods to both use Java and JavaScript. The JSNI string #com.smartgwt.client.Version::getVersion()() will be rewritten as something like $getVersion1() in PRETTY, or something just one or two characters long in OBF mode, so you can't rely on that method name being the same.
Instead, you need to export a JavaScript function from inside your application so that this external JavaScript can invoke it. Check out https://developers.google.com/web-toolkit/doc/latest/DevGuideCodingBasicsJSNI#calling for specific details on this.
Here is an example of how this might look in your application:
public native void exportGetVersion() /*-{
$wnd.getSmartGwtVersion = $entry(function() {
return #com.smartgwt.client.Version::getVersion()();
});
}-*/;
Make sure you call this function in your app somewhere to export the function - any time after that is called, you can invoke getSmartGwtVersion() from your regular JavaScript - no need to use frames or $entry.
I have some Java code written that I'd like to convert to JavaScript.
I wonder if it is possible to use the GWT compiler to compile the mentioned Java code into JavaScript code preserving all the names of the methods, variables and parameters.
I tried to compile it with code optimizations turned off using -draftCompile but the method names are mangled.
If GWT compiler can't do this, can some other tool?
Update
The Java code would have dependencies only to GWT emulated classes so the GWT compiler would definitely be able to process it.
Update 2
This Java method :
public String method()
got translated to this JavaScript funciton :
function com_client_T_$method__Lcom_client_T_2Ljava_lang_String_2()
using the compiler options :
-style DETAILED
-optimize 0
-draftCompile
So names can't be preserved. But is there a way to control how they are changed?
Clarification
Say, for example, you have a sort algorithm written in Java (or some other simple Maths utility). The method sort() takes an array of integers. and returns these integers in an array sorted. Say now, I have both Java and JavaScript applications. I want to write this method once, in Java, run it through the GWT compiler and either keep the method name the same, or have it change in a predictable way, so I can detect it and know how to change it back to sort(). I can then put that code in my JavaScript application and use it. I can also automatically re-generate it if the Java version changes. I have a very good reason technically for this, I understand the concepts of GWT at a high level, I'm just looking for an answer to this point only.
Conclusion
The answer to the main question is NO.
While method name can be somewhat preserved, its body is not usable. Method calls inside it are scattered throughout the generated file and as such, they can't be used in a JavaScript library which was the whole point of this topic.
Although you can set the compiler to output 'pretty' code, I suggest you write export functions for the classes you want to call from outside your GWT project. I believe somewhere in the GWT documentation it's detailed how to do this, but I couldn't find it so here an example I just created.
class YourClass {
public YourClass() {
...
}
public void yourMethod() {
...
}
public static YourClass create() {
return new YourClass();
}
public final static native void export() /*-{
$wnd.YourClass = function() {
this.instance = new #your.package.name.YourClass::create()()
}
var _ = $wnd.YourClass.prototype;
_.yourMethod = function() {this.instance.#your.package.name.YourClass::yourMethod()()}
}-*/;
}
EDIT
To elaborate, your code will get obfuscated like normal, but thanks to the export function, you can easily reference those functions externally. You don't have to rewrite anything from your Java class in JavaScript. You only write the references in JavaScript, so you can do this:
var myInstance = new YourClass();
myInstance.yourMethod();
Of course you have to call the static export method from somewhere in your GWT app (most likely in your EntryPoint) to make this work.
More info about referencing Java methods from JavaScript:
http://code.google.com/webtoolkit/doc/latest/DevGuideCodingBasicsJSNI.html#methods-fields
No - this isn't possible with the GWT compiler, since the GWT compiler is build to generate optimized and very performant JavaScript out of Java.
The big advantage is, that you can maintain your projekt in Java and compile it with GWT to JavaScript. So there is no need to prevent the variable-names and method-names in the JavaScript result, since all changes and work is done in the JAVA-sources.
Working in the JavaScript-output of GWT just isn't that easy and is really a lot of work!
Update:
By a hint of David, I found the Compiler-Option "-style". You can have a try with the following options:
-style=PRETTY -optimize=0
I have no idea if this will really generate "human readable" code. I think it won't, since the GWT framework will still be part of the resulting JavaScript and so it will be difficult to make changes to the JavaScript-result. Have a try and let us know ...
Maybe I can answer your second question: "If GWT compiler can't do this, can some other tool?"
I am using Java2Script for quite a while now, also on quite large projects. Integration with native JavaScript is fine, names are preserved, and after some time one can even match the generated JavaScript (in the browser debugger) with the original Java code with little effort.
Udo
You can "export" your function by writing inline JavaScript that calls it, and there is a tool gwt-exporter that does this automatically when you annotate classes and methods with #Export and similar. More information: https://code.google.com/p/gwtchismes/wiki/Tutorial_ExportingGwtLibrariesToJavascript_en