Haxe use of #:classCode - java

I can't find a single example of how #:classCode is used (to inject a native member directly into the file). This fails with Unexpected untyped at compile time:
#:classCode
untyped __java__("public void paintComponent(Graphics g) {doStuff();}");
I can't simply use standard Haxe code to have a paintComponent() method because of the way Haxe eats #:overload methods (and forces use of #:overload in the first place).

There are some examples of it in the Haxe standard library, for instance:
#:classCode('override public string Message { get { return this.toString(); } }\n\n')
#:nativeGen #:keep #:native("haxe.lang.HaxeException")
private class HaxeException extends Exception
Looks like the class code metadata has a string argument containing the code to be inserted and should be used on a class declaration.

Related

How do I use a Java-defined instance method in Lua?

I'm aware that it is possible to use Java defined static methods in Lua, due to the section "Libraries of Java Functions" on http://luaj.org/luaj/README.html.
However I am struggling to find out how I can use the same for instance methods, I have a shortened example here:
private static class CallbackStore {
public void test(final String test) {
}
}
(I am aware that I can use a static method here as well, but it is not possible with the real life scenario)
I am using the following Lua code:
-- Always name this function "initCallbacks"
function initCallbacks(callbackStore)
callbackStore.test("test")
end
Which does not work as it is expecting userdata back, but I give it a string.
And I call the Lua code like this:
globals.load(new StringReader(codeTextArea.getText()), "interopTest").call();
CallbackStore callbackStore = new CallbackStore();
LuaValue initCallbacks = globals.get("initCallbacks");
initCallbacks.invoke(CoerceJavaToLua.coerce(callbackStore));
where the Lua code is returned by codeTextArea.getText()
Bottom line of my question is, how do I make my code running with test as an instance method?
When accessing member functions (in Lua objects in general, not just luaj) you have to provide the this argument manually as the first argument like so:
callbackStore.test(callbackStore,"test")
Or, you can use the shorthand notation for the same thing:
callbackStore:test("test")

getting a method object for a class with compile time checking (in java)

I would like to get a Method object similar to this:
Method myMethod = MyClass.class.getDeclaredMethod("myDeclaredMethod",Arg1Class.class);
But! I would like compile time checking of the existence of the method "myDeclaredMethod". I don't actually need to dynamically choose the method, I just need a reference to it so I can pass it to another method... similar to the way C has function pointers. I'd like to do something like this:
#include <stdio.h>
void helloWorld() {
printf("hello\n");
}
void runFunction( void (myfunc)() ) {
myfunc();
}
int main() {
runFunction(helloWorld);
return 0;
}
Notice, if I mistype "helloWorld" in the call "runFunction(helloWorld)", I get a compile time error. I want that same compile time error in Java, if possible.
I'm afraid you can't do that in Java.
However, the usual way to achieve this in Java is to define an interface that will declare only one method, the one you want to "pass as argument", and implement it in a class. Your class has to implement the method you are interested in. When you want to pass a "reference" to the method, you actually pass an instance of your interface. You can call your method on it.
An example might explain this:
interface Something {
void doSomething();
}
class HelloWorld {
void doSomething() {
System.out.println("Hello world");
}
}
class Main {
void runFunc(Something s) {
s.doSomething();
}
public static void main(String... args) {
runFunc(new HelloWorld());
}
}
The problem is, if you want to call another method you need to create a new class implementing Something
This is not possible in Java: methods are not first-class citizens in Java.
But it is possible to do in Scala!
You could write an annotations processor which using private APIs in the JDK check the the methods invoked via the reflection API and occassionally halt the compilation process.
This is detailed in Compile-Time Checked Reflection API as is done by dp4j.
If you use dp4j with #Reflect or JUnit's #Test annotations you get the compile-time checking when you call the method 'normally', as in myDeclaredMethod(new Arg1Class())

JRuby calls the wrong method

I got a strange problem with a call to a Java method from JRuby.
In my Java class these methods are defined twice, and it appears JRuby calls the wrong one.
So I tried to use java_method, but I always got a:
TypeError: cannot convert instance of class org.jruby.RubyModule to class java.lang.Class
Here's my Java code:
public class Renderer {
...
public void addRenderer(IElementRenderer r) {
System.out.println("Added element render: " + r.getClass().toString());
basicRenderers.add(r);
rendererMap.put(r.elementClass(), r);
}
public void addRenderer(IBasicRenderer r) {
System.out.println("SHOULD NOT GO THERE !!");
basicRenderers.add(r);
}
}
and my JRuby code:
add_renderer = renderer.java_method :add_renderer, [Java::dragon.render.IElementRenderer]
add_renderer.call TextRenderer.new
I also tried with java_send but I got the same error:
renderer.java_send(:add_renderer, [Java::dragon.render.IElementRenderer], TextRenderer.new)
Next, I tried with:
renderer.add_renderer(TextRenderer.new.to_java(IElementRenderer))
This time no errors but the wrong method is called ...
How can I fix this problem?
You can fix that cannot convert instance of class org.jruby.RubyModule to class java.lang.Class using java.lang.Class.for_name
In your case, it is
add_renderer = renderer.java_method :add_renderer, [java.lang.Class.for_name("dragon.render.IElementRenderer")]
This is because java interfaces become Ruby Modules by default and the second argument to :java_method expects an array of Class objects.
You can print the matched method to see it is matching the intended method.
For example, I see below code is matching the println(String) on System.out.
>>java.lang.System.out.java_method "println", [java.lang.Class.for_name("java.lang.String")]
#<Method: Java::JavaIo::PrintStream#(java.lang.String)>
I've had problems like this before. It was many versions ago and I think JRuby's method matching algorithm has improvedd over time. Are you using the latest JRuby?
If nothing else works, you may need to add another method, or a wrapper class. Something that distinguishes your methods by name or number of parameters, not just parameter type.

Can you use Java Reflection api in GWT client

IS it possible to use the java reflection api in GWT client side? I want to use reflections to find the value of a property on a Javabean. Is this possible?
You can use the GWT Generators functionality that allows you to generate code during the GWT compile phase.
Your bean, that you want to introspect, can extend a class that has a method defined as
public Object getProperty(String propertyName){}
Let's call this class IntrospectionBean.
Let's say that you then have your bean defined as:
public class MyBean extends IntrospectionBean {
private String prop1;
private String prop2;
}
The GWT generator will have access to all fields of MyBean and it can generate the getProperty(String propertyName) method during GWT compile time, after iterating through all fields of MyBean.
The generated class might look like this:
public class MyBean extends IntrospectionBean {
private String prop1;
private String prop2;
public Object getProperty(String propertyName) {
if ("propr1".equals(propertyName)) {
return prop1;
}
if ("propr2".equals(propertyName)) {
return prop2;
}
return null;
}
}
You could simply then use myBean.getProperty("prop1") in order to retrieve a property based on it's name at runtime.
Here you can find an example of how to implement a gwt generator
I've been there and the solution indeed is to use Deferred Binding and Generators. You can see a use of Generators to overcome the lack of Reflection in GWT client here:
http://jpereira.eu/2011/01/30/wheres-my-java-reflection/
Hope it helps.
Since GWT code is translated to Javascript direct usage of reflection API is not supported.
There is a small project GWT-Reflection, that allows to use reflection in GWT.
I have made my gwt-reflection library public.
https://github.com/WeTheInternet/xapi/tree/master/gwt/gwt-reflect
https://github.com/WeTheInternet/gwt-sandbox/tree/xapi-gwt/user/src/com/google/gwt/reflect
Due to classpath issues with trying to make Gwt pick my version of Class.java over its own, I finally just forked Gwt, added java 8 and reflection support, and now maintain net.wetheinter:gwt-*:2.7.0 which has this support baked in (I will release a 2.8 some time after Gwt 2.8 goes live)
It supports three levels of reflection:
Monolithic:
// Embeds all data needed to perform reflection into hidden fields of class
GwtReflect.magicClass(SomeClass.class);
SomeClass.getField(fieldName).set(null, 1);
Lightweight:
// Allows direct reflection, provided ALL parameters are literals, or traced to literals
SomeClass.class.getField("FIELD_NAME").set(null, 1);
Flyweight:
// Skips creating a Field object entirely, and just invokes the accessor you want
// All params must be literals here as well
GwtReflect.set(SomeClass.class, "FIELD_NAME", null, 1);
These examples also work for Methods and Constructors. There's basic support for annotations, and more to come in the future.
GWT not support reflection fully, you can see bellow link :
http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsCompatibility.html
You should note the border between java and javascript. In GWT, all code compiles to javascript, so you have to check if JavaScript is a well-defined reflection.
If you just want to use reflection to grab a private field, consider using jsni (javascript native interface) instead; it has no notion of private or public, so you can just grab anything you want like so:
package com.foo;
class SomeClass {
private String someField;
private static int someInt;
}
//accessors:
native String ripField(SomeClass from)
/*-{
return from.#com.foo.SomeClass::someField;
}-*/;
native int ripInt()
/*-{
return #com.foo.SomeClass::someInt;
}-*/;
Also, I am in the middle of finishing up emulation for java.lang.Class newInstance / reflection.
I'll post back here with a link in about two days if you'd like to play with it.
It requires that you pass a class through a method which I route to a custom generator
(like GWT.create, except it returns a generated java.lang.Class with field and method accessors that just point to jsni methods / fields. :)

How to Read Java File Structure using Java?

I'm trying to read a java file and display in console the package, class and method name. something like this:
File: Test.java
package tspec.test;
public class Test {
public void addTest () {}
public void deleteTest () {}
}
Output:
package name: tspec.test
class name: Test
method name:
addTest
deleteTest
Thanks in advance :)
This can be accomplished using the Java Compiler API (introduced in Java 6). Unfortunately, this solution is limited to Sun's JDK. Therefore, you will have to have that JDK installed and you must include its tools.jar file in your class path.
public void displayInformation(File javaSourceFile) throws Exception {
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
// The file manager locates your Java source file for the compiler. Null arguments indicate I am comfortable with its default behavior.
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
// These will be parsed by the compiler
Iterable<? extends JavaFileObject> fileObjects = fileManager.getJavaFileObjects(javaSourceFile);
// Creates a new compilation task. This doesn't actually start the compilation process.
// Null arguments indicate I am comfortable with its default behavior.
CompilationTask task = compiler.getTask(null, null, null, null, null, fileObjects);
// Cast to the Sun-specific CompilationTask.
com.sun.tools.javac.api.JavacTaskImpl javacTask = (com.sun.tools.javac.api.JavacTaskImpl) task;
// The Sun-specific JavacTaskImpl can parse the source file without compiling it, returning
// one CompilationUnitTree for each JavaFileObject given to the compiler.getTask call (only one in our case).
Iterable<? extends CompilationUnitTree> trees = javacTask.parse();
CompilationUnitTree tree = trees.iterator().next();
// Create a class that implements the com.sun.source.tree.TreeVisitor interface.
// The com.sun.source.util.TreeScanner is a good choice because it already implements most of the logic.
// We just override the methods we're interested in.
class MyTreeVisitor extends TreeScanner<Void, Void> {
#Override
public Void visitClass(ClassTree classTree, Void p) {
System.out.println("class name: " + classTree.getSimpleName());
System.out.println("method name:");
return super.visitClass(classTree, p);
}
#Override
public Void visitMethod(MethodTree methodTree, Void p) {
System.out.println(methodTree.getName());
return super.visitMethod(methodTree, p);
}
}
tree.accept(new MyTreeVisitor(), null);
}
When I pass this method a File whose content is your sample, I receive this output:
class name: Test
method name:
addTest
deleteTest
Unfortunately, I haven't yet figured out where the package name is stored.
Reflection and Introspection Java API's.
It's purpose is to introspect Java code and report back about it's contents. With Reflection you can do things like :
Class.forName(className).getDeclaredMethods();
Java also has the Java Mirror API with similiar functionality, but is not as commonly used.
Both of these solutions require no 3rd party libraries or tools.
The only difficult is the java code may not be well formatted. like the function declaration can be spread on multiple lines.
The ultimate solution is to create an automata to tokenize the source code first and then apply some compiler technique to grab what you want from the parsed data.
We use PMD Java code analyzer to solve similar problem.
It is useful.
http://pmd.sourceforge.net/
You don't have to do this by parsing the Java file yourself! Java already contains a way of getting information about its own classes, methods, and packages: it's called reflection.
Have a look at the java.lang.Class class. Each instance of this class represents a particular Java class, and contains methods to return the class name, the package it lives in, the methods it contains, and lots more information.
Also worth looking at is the java.lang.reflect package, since some of the methods of Class return types from this package. The package contains classes to represent things like methods, types, fields, and so on.
To obtain a Class instance of your Test class, you can use the following code:
Class<?> testclass = Class.forName("tspec.test.Test");
This returns a class of an unknown type, which is what the question mark inside the angle brackets means if you're not familiar with generics. Why the type of the class instance is unknown is because you specify the class name with a string, which is parsed at runtime. At compile-time, Java cannot be sure that the string passed to forName even represent a valid class at all.
However, testclass as defined above will be fine for getting the class's name, methods, and containing package.

Categories

Resources