I'm using JPL to do some SWI-Prolog queries in a Java program. When I want to create a new Query, I would like to be able to use jpl.Util.textToTerm to directly instanciate Terms from a user input, without parsing it myself.
The problem is that this method seems to always parse variable identifiers (i.e. something that starts with a capital letter) as anonymous variables (i.e. something that starts with _).
For example, jpl.Util.textToTerm("X") returns a jpl.Variable that has name _1 instead of X, which is obviously a problem since that means I won't be able to access any bindings after querying.
Creating a jpl.Query directly from a string, like new Query("reverse([1,2],X)") has the exact same problem.
_1 it's not an anonymous variable, so the problem is less important than it appears at first glance.
Variables with the same name (actually, the same variable) will have the same representation once returned from the JPL interface. Otherwise, you should file a bug of the mailing list...
You should use read_term family of predicates passing as option variable_names(Vars). For instance, on the REPL
?- read_term_from_atom('a(X,Y,X)',T,[variable_names(L)]).
T = a(_G1434, _G1435, _G1434),
L = ['X'=_G1434, 'Y'=_G1435].
edit a quick test reusing JPL test infrastructure (I've named the file TestQuery.java)
import java.util.Map;
import org.jpl7.Query;
import org.jpl7.Term;
public class TestQuery {
public static void main(String argv[]) {
Query q = new Query("X = 1");
Map<String, Term>[] solutions = q.allSolutions();
System.out.println(solutions[0]);
}
}
outputs
./run.sh
Compiling TestQuery
JPL demo: TestQuery
{X=1}
so, maybe I don't understand your problem in first place, sorry... Are you using an up-to-date installation ?
Related
I've been playing around with the jdk.incubator.foreign stuff in JDK-18. It's pretty nice. WAY faster than JNI. An order of magnitude faster. The foreign memory stuff is better (and maybe slightly faster) than the UNSAFE stuff. Can't wait for this to ship.
One thing I can't figure out: How to upCall to a non-static JVM function?
If I can't, how do I pass some context down and back so I can cast the context into the correct instance/type in the java static function? In java how do you create a ValueLayout.ADDRESS from this? And vice-versa?
The only way I can figure out how to do it is to keep a list of instantiated classes, and round-trip the index in the list. Which seems like a hack.
Maybe the JVM reserves the right to move JVM memory around without restriction whenever it feels like it, so maybe it's not possible? If so, what is the recommended pattern for this?
--- edit - Add code example ---
public class RoundTripExample {
private String name;
RoundTripExample(String _name) {
this.name = _name;
}
public void callback() {
System.out.println("Called from native"+name);
}
public static void main(String[] args) throws Throwable {
var fName = new File("../zig/zig-out/lib/libnativeFuncs.so").getCanonicalFile();
System.load(fName.toString());
var instance =new RoundTripExample("round trip name");
CLinker link = CLinker.systemCLinker();
SymbolLookup symLook = SymbolLookup.loaderLookup();
ResourceScope scope = ResourceScope.newSharedScope();
var nativeFunc = link.downcallHandle(
symLook.lookup("zigCallTest").get(),
FunctionDescriptor.of(ValueLayout.ADDRESS, ValueLayout.ADDRESS)
);
var handle =
MethodHandles.lookup().findVirtual(
RoundTripExample.class,
"callback",
MethodType.methodType(void.class)
);
handle.bindTo(instance);
var upcall = link.upcallStub(
handle,
FunctionDescriptor.ofVoid(ValueLayout.ADDRESS),
ZigStubs.scope
);
nativeFunc.invoke(upcall);
}
}
Assuming this is the way to do it, the problem is creating the upCall handle. You can only pass it a handle to functions that take LONG, INT, ADDRESS, etc. An instance of a class isn't any of those.
If the context you need to pass is constant for the target function, you could bind it to the target method handle using MethodHandles.insertArguments and then use the resulting method handle to create an upcall stub.
If the context is not constant for the target function, then your idea of using a list and passing around the index to the object you want is a pretty good way to go. This is essentially a way to turn an object into an integer, by inserting it into the list, and then back into an object by looking it up in the list again.
There's no safe way of turning an object into a plain native address, since, as you say, the object might be move by the JVM.
In the example, using bindTo looks feasible. In this case you've forgotten to assign the result of bindTo:
handle = handle.bindTo(instance);
Additionally, you'd have to drop the address argument passed from native code, as it looks like it's not being used by your Java code:
handle = MethodHandles.dropArguments(handle, 0, MemoryAddress.class);
var upcall = link.upcallStub(
handle,
FunctionDescriptor.ofVoid(ValueLayout.ADDRESS),
ZigStubs.scope
);
I'm developing a "macro" for OpenOffice Calc. As the language, I chose Java, in order to get code assistance in Eclipse. I even wrote a small ant build script that compiles and embeds the "macro" in an *.ods file. In general, this works fine and surprisingly fast; I'm already using some simple stuff quite successfully.
BUT
So often I get stuck because with UNO, I need to "query" an interface for any given non-trivial object, to be able to access data / call methods of that object. I.e., I literally need to guess which interfaces a given object may provide. This is not at all obvious and not even visible during Java development (through some sort of meta-information, reflection or the like), and also sparsely documented (I downloaded tons of stuff, but I don't find the source or maybe JavaDoc for the interfaces I'm using, like XButton, XPropertySet, etc. - XButton has setLabel, but not getLabel - what??).
There is online documentation (for the most fundamental concepts, which is not bad at all!), but it lacks many details that I'm faced with. It always magically stops exactly at the point I need to solve.
I'm willing to look at the C++ code to get a clue what interfaces an object (e.g. the button / event I'm currently stuck with) may provide. Confusingly, the C++ class and file names don't exactly match the Java interfaces. It's almost what I'm looking for, but then in Java I don't really find the equivalent, or calling queryInterface on a given object returns null.. It's becoming a bit frustrating.
How are the UNO Java interfaces generated? Is there some kind of documentation in the code that serves as the origin for the generated (Java) code?
I think I really need to know what interfaces are available at which point, in order to become a bit more fluent during Java-UNO-macro development.
For any serious UNO project, use an introspection tool.
As an example, I created a button in Calc, then used the Java Object Inspector to browse to the button.
Right-clicking and choosing "Add to Source Code" generated the following.
import com.sun.star.awt.XControlModel;
import com.sun.star.beans.XPropertySet;
import com.sun.star.container.XIndexAccess;
import com.sun.star.container.XNameAccess;
import com.sun.star.drawing.XControlShape;
import com.sun.star.drawing.XDrawPage;
import com.sun.star.drawing.XDrawPageSupplier;
import com.sun.star.sheet.XSpreadsheetDocument;
import com.sun.star.sheet.XSpreadsheets;
import com.sun.star.uno.AnyConverter;
import com.sun.star.uno.UnoRuntime;
import com.sun.star.uno.XInterface;
//...
public void codesnippet(XInterface _oUnoEntryObject){
try{
XSpreadsheetDocument xSpreadsheetDocument = (XSpreadsheetDocument) UnoRuntime.queryInterface(XSpreadsheetDocument.class, _oUnoEntryObject);
XSpreadsheets xSpreadsheets = xSpreadsheetDocument.getSheets();
XNameAccess xNameAccess = (XNameAccess) UnoRuntime.queryInterface(XNameAccess.class, xSpreadsheets);
Object oName = xNameAccess.getByName("Sheet1");
XDrawPageSupplier xDrawPageSupplier = (XDrawPageSupplier) UnoRuntime.queryInterface(XDrawPageSupplier.class, oName);
XDrawPage xDrawPage = xDrawPageSupplier.getDrawPage();
XIndexAccess xIndexAccess = (XIndexAccess) UnoRuntime.queryInterface(XIndexAccess.class, xDrawPage);
Object oIndex = xIndexAccess.getByIndex(0);
XControlShape xControlShape = (XControlShape) UnoRuntime.queryInterface(XControlShape.class, oIndex);
XControlModel xControlModel = xControlShape.getControl();
XPropertySet xPropertySet = (XPropertySet) UnoRuntime.queryInterface(XPropertySet.class, xControlModel);
String sLabel = AnyConverter.toString(xPropertySet.getPropertyValue("Label"));
}catch (com.sun.star.beans.UnknownPropertyException e){
e.printStackTrace(System.out);
//Enter your Code here...
}catch (com.sun.star.lang.WrappedTargetException e2){
e2.printStackTrace(System.out);
//Enter your Code here...
}catch (com.sun.star.lang.IllegalArgumentException e3){
e3.printStackTrace(System.out);
//Enter your Code here...
}
}
//...
Python-UNO may be better than Java because it does not require querying specific interfaces. Also XrayTool and MRI are easier to use than the Java Object Inspector.
Today I came across an obfuscated class (well a lot of obfuscated classes in a jar) and I do not have a clue on how this kind of obfuscation is done.
An example:
protected void a(ChannelHandlerContext ☃, ByteBuf ☃, ByteBuf ☃)
throws Exception
{
int ☃ = ☃.readableBytes();
if (☃ < this.c)
{
☃.b(0);
☃.writeBytes(☃);
}
else
{
byte[] ☃ = new byte[☃];
☃.readBytes(☃);
☃.b(☃.length);
this.b.setInput(☃, 0, ☃);
this.b.finish();
while (!this.b.finished())
{
int ☃ = this.b.deflate(this.a);
☃.writeBytes(this.a, 0, ☃);
}
this.b.reset();
}
}
}
As you see above, all the parameter variables are a snow-man. How can this be undone? Also how is it done in the first place; how is the JVM able to "process" those and execute the code without any problem?
To clarify, I am not going to use this code, it is just for educational purposes. I am taking the Computer Science course at school so since we are learning Java and talking of limitations such as decompilations. I am interested in learning more, so I decided to have a look into bigger projects especially servers. This piece of code is pulled out of the Spigot server for Minecraft (A game) that is a fork of Bukkit server for Minecraft that was supposed to be open source.
First of all, you should note that it is the parameters which have this unicode and not the methods. Why is this important?
Parameters do not need to have names specified, as they are mostly indexed by a number reference. However it can be specified and I assume that most java runtimes do in fact not check this name as it is not needed for execution.
In the opposite, class names, method names, and field names are however needed.
About you mentioning Spigot, Spigot is indeed open source. However you most likely decompiled a class which is originally from the original Mojang Minecraft server, which is not open source and is indeed obfuscated.
Edit: In the case you want to investigate these classes, I recently found a tool called Bytecode Viewer, which is available at https://github.com/Konloch/bytecode-viewer
This tool has multiple decompilers as well as some options to view a more bytecode like version of the class file.
An example of a function I found contains the following bytecode data:
<localVar:index=1 , name=☃ , desc=D, sig=null, start=L1, end=L2>
<localVar:index=3 , name=☃ , desc=D, sig=null, start=L1, end=L2>
<localVar:index=5 , name=☃ , desc=D, sig=null, start=L1, end=L2>
Indeed as is visible, the unicode name has been set the same, but it does not matter as in the end the indexes (1,3,5) are used to reference these variables.
protected void a(ChannelHandlerContext ☃, ByteBuf ☃, ByteBuf ☃)
This isn't valid. You cannot have multiple parameters with the same name. It could be that you are not reading the unicode text with the right text format.
Your Text editor is showing the value of the unicode character.
I just tested on eclipse and names with unicode characters are acceptable.
public String publicationXmlUrl(int \u9090currentPage) {
But writing with values are not:
public String publicationXmlUrl(int ♥currentPage) {
I've written a class which accepts a generic type, and I'm trying to create an array list of generic arrays within it. I understand that Java can't create generic arrays, but I also know there are workarounds. Is there a way the below code can work, or am I barking up the wrong tree?
public class IterableContainer<T extends IterableItem> {
private T[] itemArray;
// how can i get this following line to work?
private List<T[]> items = new ArrayList<T[10]>();
public IterableContainer() {
... etc ...
Ignore past here - turns out it was an IDE issue.
Left in for continuity of questions and answers.
EDIT:
This also doesn't work:
private List<T[]> items = new ArrayList<T[]>();
with the error:
Syntax error on token ">", VariableDeclaratorId expected after this token
"... barking up the wrong tree..., use a List<List<T>>. Using raw arrays in Java is almost always a code smell, there is no reason not to use the proper collection classes.
It works just fine, you just can't use the T[10] declaration as the length of an array doesn't affect its type.
i.e.
... = new ArrayList<T[]>();
Not saying it's a great idea, but it should be possible with the same restrictions on generic arrays as always. Creating stuff to put in your list will give you a headache.
private List<T[]> items = new ArrayList<T[]>();
works fine in my machine
When you say "I'm developing for mobile devices" ....are you targeting j2me? There is no support for generics in j2metargetng
This is a valid declaration in java (according to spec) and compiles just fine with javac as others have commented.
public class IterableContainer<T extends IterableItem> {
private T[] itemArray;
private List<T[]> items = new ArrayList<T[]>();// valid
..........
}
I believe the error you are seeing is not emitted from Eclipse, possibly coming from an Android SDK configured in Eclipse. If you create a Java Project in Eclipse, this code should work just fine. If you use this in an Android Project in Eclipse, you are likely to run into this one. I had this error when running this code from an Android project :
# guarantee(_name_index != 0 && _signature_index != 0) failed: bad constant pool index for fieldDescriptor
Sounds like you are restricted in an Android project, unfortunately.
You have not defined T in this code.
If you are creating a generic class, you need to write:
public class <T extends IterableItem> IterableContainer...
The next problem in your code is that you are trying to initilize items of ArrayList during its construction. It is impossible. You should rather write:
private List<T[]> items = new ArrayList<T[]>();
I am working on a legacy project that is using Oracle Forms 6i (yes, I know its old) to call C++ functions from a PLL library.
Now we need to use Java instead of C++, therefore we need to call Java (Object/Class/Method) from Oracle Forms.
I know its a challenging subject, but I would be really happy if someone could provide a simple example that does the following:
Invoking a method from the Java class, passing a int variable (within PL/SQL)
Printing the returned value in the Canvas that executed the Function.
A basic example, perhaps a Hello World would be ideal.
I know some PL/SQL, but I am not a Oracle Forms developer; please bear with me.
If this is not possible, could you point me to some other alternatives?
Well, after an intensive lookup through the internet I came across a very good resource (in Spanish though): Elias blog about Oracle Forms and Java
I use:
Oracle Forms 6i
JDK 1.6
With this I managed to create the hello world example:
Configure PATH environment variables:
C:\PATH_TO_JAVA\Java\jdk1.6.0\bin;
C:\PATH_TO_JAVA\Java\jdk1.6.0\jre\bin;
C:\PATH_TO_JAVA\Java\jdk1.6.0\jre\bin\client;
Ex: PATH_TO_JAVA = C:\Program Files
Add to CLASSPATH
FORMS_HOME\TOOLS\common60\JAVA\IMPORTER.JAR (In my case FORMS_HOME was C:\orant)
PATH_TO_YOUR_JAR\NAME_OF_JAR.jar
Create Java Program
Create with your IDE a simple java program, following is mine:
public class HiWorld{
private String hi="Hello World!";
public String getHi(){
return this.hi;
}
public String getMultiply(int a, int b){
return ""+a*b;
}
public static void main(String args[]){
HiWorld hm = new HiWorld();
System.out.println(hm.getHi());
System.out.println(hm.getMultiply(5,10));
}
}
Export it to Jar file (Path has to be the one you put in CLASSPATH environment variable.
Import the classes to Forms
Create a new project in Oracle Forms and also create a Canvas, in the canvas use a Text and a Button. The name of the button: TEXT_HI_WORLD.
Following click on the Menu: Program > Import Java Classes
If everything went Ok then there will be a new window that will show you the package where the Class is, you extend it until there is the HiWorld class. Import it.
In Program Unit now there will be two files:
HIWORLD (Specification)
HIWORLD (Body)
This are files generated automatically and needed to use the class.
Then go back to the canvas, right click on the Button and select the Thrigger WHEN-BUTTON-PRESSED, the programming of this will be:
DECLARE
v_wb ORA_JAVA.JOBJECT;
v_hi VARCHAR2(20);
BEGIN
v_wb := hiworld.new();
v_hi:= hiworld.getHi(v_wb);
:TEXT_HI_WORLD := v_hi
END;
Now execute the program and click on the button! :)
Hope this helps Java programmers with no much of knowledge on Forms to integrate with legacy systems! :D
I've done this before, and with a simple class this should work, but when you try to develop something more complicated, I recommend extend from the VBean class, you can find the library within oracle's forms installation folders (frmall.jar).
// el programa corregido.
public class HolaMundo {
private String hi= "Hey World!!!";
public String GetHi(){
return this.hi;
}
public static void main(String args[]){
HolaMundo hm = new HolaMundo();
System.out.println(hm.GetHi());
}
}