I have a java program that processes information, but I want to make it so the end user can write javascripts that dictate what to do with this info. Like this
//Java
private void newData(int var1) {
script.newData(var1);
}
and then
//Javascript
function newData(var var1) {
someVar = var1;
processVar();
}
I have looked into something called rhino, but I really am having trouble understanding the concept of rhino. Anyone know what to do?
You want Rhino. Rhino is a javascript runtime implemented in Java. It is suitable for embedding in Java applications.
What you want to do is create your Java classes and objects and then make them accessible to a Javascript environment. Fortunately this is very easy with Rhino. Read this tutorial and pay close attention to the first and second sections (RunScript: A simple embedding and Expose Java APIs).
The first section is about executing Javascript within a Java application. You will need to adapt their sample code a little to provide some way for the end user to hand javascript code to you (in a file or stream) for you to execute. It won't be difficult.
The second section is about making your Java stuff available to the Javascript stuff. In the simplest case you don't need to do anything--all of Java is available to Rhino javascript automatically. But you can very easily pretty up the interface and provide something easier for the end user to use if you want.
With Rhino you can also go in the other direction--you can make Javascript objects available to the Java environment. This is a little more complicated, but is covered in the rest of the tutorial. You may not need to do this either.
Related
I'm making a system for an app, witch have for objective to allow the user to create custom script to interact with the program by handleing events and reacting to them by calling functions. The main program is wrote in java, but If want to allow the script to be wrote in JavaScript. What is the best way to do that ?
I've tryed to use the sockets to transfer data and events, but I thinks it's a bit overkill, because the app and the scripts are on the same machine. Does it exist a better way to do that?
If I understand correctly, what you want to do is called Remote Procedure Call and it doesn't help much that all your code (java and js) runs on the same computer. But you can probably at least get away without authentication or security.
There are a bunch of libraries that may save you some trouble. You may want to take a look at those options:
https://en.wikipedia.org/wiki/Remote_procedure_call#General
I only got the occasion of using one: json-rpc, which isn't necessarily the best option, but it is the only one I can give you more details about.
The specification of the protocol is available here https://www.jsonrpc.org/specification and there should be Java and Javascript libraries to ease the implementation.
For example:
Java - https://github.com/briandilley/jsonrpc4j
Javascript - https://github.com/jershell/simple-jsonrpc-js
Calling this Java hello method:
public String hello(#JsonRpcParam(value="message") String message) {
return message;
}
From your client, a call to hello would look like this:
var jrpc = simple_jsonrpc.connect_xhr('localhost:8080');
jrpc.call('hello', {message: 'hello world!'}).then(res => console.log(res));
Of course there's additional configuration, at least on sever (java) side to make this work.
I am looking for a way to find the name of the program (in my code) that will launch when an operating system tries to open a given file. I will not be launching the application I'm just looking for its name. Ideally the routine I'm looking for/building would take a filename and return a string. I am programming in Java 8 on Eclipse and need my jar file to stay cross platform.
Simplest solution I can find is to use SWT's class 'Program'. Although this assumes that I can correctly identify filetype which is another big can of worms I'm not going to into here.
String ext = extractFileType(filename);
Program p2 = Program.findProgram(ext);
if (p2 != null) programName = p2.toString();
But for a number of reasons I DON'T WANT TO USE the SWT library if at all possible. I'm using Swing and and I really don't want my clients to need to download a different application (jar) dependent on their operating system. I'm well aware that the underlying code is operating system/Window Manager dependent.
Anyone know of any other package besides SWT that already does this? I can't find one. Or similar enough I can strip the results to get what I want? Even if it's only for one platform? I'm experimenting with Apache Tika but I don't see anything helpful there.
Any hints on where to look to start write this myself? I know this entails reading the registry on Windows. I need this code to work on the most recent versions of Windows, and OS X. And eventually Linux but Linux windowing systems are not a priority.
Is there a way to link/load SWT in Eclipse to make the cross-dependent part of using SWT this code a little more lightweight and invisible to the end user? I'm not new to coding but am to using Eclipse.
Here is a quick description of my solution. I did a fair amount of hunting around and I deciding on simply using the JNA library. https://github.com/java-native-access/jna and writing my own native library on a Macintosh to get it to work.
Windows: Fairly straight forward usage of JNA. I'm calling FindExecutable & PathFindExtension from JNA.
public interface MyShell32 extends Shell32 {
MyShell32 INSTANCE = (MyShell32) Native.loadLibrary("shell32", MyShell32.class, W32APIOptions.DEFAULT_OPTIONS);
WinDef.HINSTANCE FindExecutable(String lpFile, String lpDirectory, char[] lpResult);
}
{
...
char[] returnBuffer = new char[WinDef.MAX_PATH];
shell.FindExecutable(filename, null, returnBuffer);
app = Native.toString(returnBuffer);
...
}
PathFindExtention() call is similar but returns a pointer so it's more straight forward.
Macintosh: I tried all sorts of things and finally decided to write my own tiny native library to call in objective C
rtnValue = [[NSWorkspace sharedWorkspace] getInfoForFile:filenameNS
application:&AStr
type:&TStr];
This library is tiny (but I may add to it if I need other native calls) but I need to write a C/C++ shell as well as the Objective C to get it to work. I then call this library JNA. Not that different from writing straight JNI but I found it easier to code.
public interface NSWWraper extends Library {
/** The instance **/
NSWWraper INSTANCE = (NSWWraper) Native.loadLibrary("NSWWraper", NSWWraper.class);
// CP_NSWWraper
Pointer FindFileInfo(String filename);
void FreeMem(Pointer memory);
}
I honestly haven't tested this calling this a large number of files so I don't know how much it slows down my code. JNA calls are supposed to be expensive. It's interesting timing on someone asking for my solution as I'd had to put this on back burner and only got it working on Windows yesterday. I was going to incorporate this into the rest of my project today.
Edited to add. I didn't use JINI because I found it's not being very well supported on a Macintosh anymore and JNA was the better solution for Windows and I had to use it anyway.
To make my question abit more specific I'm wondering if a compiled java program can import methods from a simple "text.txt" file, basiclly from text characters?? Is this possible? If so how?
Yes it is possible, here is an example of how to do it: example. On that page a string is compiled but it is the same basic principle. If you read the stuff in your text file into a string you can do the same thing.
This can be done easily using BeanShell.
http://www.beanshell.org/
Been around for years, rock solid, works.
It can, but if you want those methods to be written in standard Java then it will require a bit of technical creativity.
Essentially, you can use the "Scripting API" ( http://docs.oracle.com/javase/6/docs/technotes/guides/scripting/programmer_guide/index.html ). This API allows you to execute "scripts" in any language as part of your greater Java application. To get it to run Java, you'd need to create a ScriptEngine implementation which could take the source, run it through the compiler API ( http://docs.oracle.com/javase/6/docs/api/javax/tools/JavaCompiler.html ), and execute it.
If the method doesn't have to be coded in Java, then you can use the scripting API pretty much out-of-the-box, along with one of the standard scripting engines. (The JavaScript engine is very well tested, for example).
All methods must be part of a class.
You can only use methods in bytecode.
IFF your text file defines an unique class, you can use the Java Compiler API and reflection to use such a method.
Could someone please advise on how to get Disk_Geometry in JNA.
I know this is straight forward in C++ by creating a handle for a disk using CreateFile(), using Deviceiocontrol to query it and using DISK_GEOMETRY to get different disk attributes. I would like to be able to do the same thing in Java using JNA, but DISK_GEOMETRY type is missing in the Kernel32.
Please help.
You can easily extend the interface definitions provided with JNA to add anything that's "missing". You can add any function, structure or constant definitions that suit your purpose.
public interface MyKernel32 extends Kernel32 {
public class DISK_GEOMETRY extends Structure {
// Fill in specifics of the structure here, following the type mapping rules
// in the JNA documentation, or use [JNAerator][1] to auto-generate the mapping.
}
}
I do not know how to do this with JNA but would like to suggest you to use WMI instead. The WMI class [Win32_DiskDrive][1] seems to be a good candidate for you. It contains what you need and probably even more. Now the question is "how to call WMI from java?" There are number of ways. The simplest one is to write script using JScript or VBS and call it from java using ProcessBuilder. This way is simple and does not require dealing with native code and external libraries but could be a little bit slow because process-to-process communication is used.
Other way is to use one of available java-to-com packages. For example JaWin, JInterop, JIntegra.
I've been playing with DWR and converters for a while and I really wanted to map my Java classes to JavaScript classes. Using DWR converters, I have the option to point out what is the name of my JS constructor given a Java class. So far so good... The problem arises when my JS constructor is within a JS package-like name (just like YUI's package system, eg my.beautiful.package.MyClass). DWR's current implementation doesn't allow me to use this kind of construct, giving me a SyntaxError when I try to use it. Is there an elegant way arround this limitation?
As far as I know the this isn't possible directly. I have in my current work project experimented with enhancing each returned object on the client side with methods from a Javascript class, which gets the result that I think you are interested in.
DwrService.getThings({
callback:function(things){
for(thing in things){
YAHOO.augmentProto(thing, my.beautiful.package.MyClass);
}
// do your stuff here
}
});
I'll have to check at work on monday (now is sunday) that augmentProto is correct one to use, but I think it is. There may even be a better hook into DWR that'll allow you to do this on the fly automagically.