Dynamic Function Creation in Java - java

So I'm trying to figure out if there is some method to dynamically create/assign a method to a class in Java. If it were C, I would just do it as follows using pointers:
public class Foo {
void bar(void *ptr) {....}
};
int main() {
Foo f = new Foo();
f.bar({"my function" ...})
}
However, Java of course has no pointers, so is there any way to get a similar functionality out of a Java application?

In Java, you would normally declare an interface with a method to be called. For example, if your function simply wants to execute some code, you would declare a Runnable and implement its run method.
public class Foo {
void bar(Runnable function) {
for(int i = 0; i < 5; i++) {
function.run();
}
}
static void myFunction() {
System.out.println("my Function!");
}
public static void main(String[] ignored) {
Foo f = new Foo();
f.bar( new Runnable() { public void run() {
myFunction();
}});
}
}

To generate truly dynamic methods you need a bytecode-manipulation library, such as Javassist or cglib.

In java it is achieved by something called anonymous classes, here is an example -
abstract class Bar {
public void myfunc();
}
public class Client {
public void execute()
{
doSomething(new Bar() {
// define your dynamic function here ie provide its implementation
public void myfunc() {
//do whatever
}
});
}
public void doSomething(Bar b)
{
b.myfunc();
}
}

You can use the Java Scripting API, create the function as a Script and call it. But only do this if your functions are really completely defineable at runtime, because interpreting scripts is always slower than implementing it in native Java.

If you really want to change classes at runtime, the only way is to actually modify the bytecode, assuming your set-up allows it (Java security would normally kick in). That said, there's an java.lang.instrument package in Java 6 which may help:
http://download.oracle.com/javase/6/docs/api/java/lang/instrument/package-summary.html
You might find the cglib project of use also:
http://sourceforge.net/projects/cglib/

See http://functionaljava.org/ for a whole functional library for Java.

Here's a link to how you can use the built in runtime version of javac to compile classes you define on the fly.

Related

Lambda body isn’t executed unless corresponding method is invoked

I am learning about Java Lambdas and I asked myself is it always required to call a abstract method of functional interface if I want to use the lambda here?
#FunctionalInterface
public interface A {
public void somefunction();
}
#FunctionalInterface
public interface B extends A {
}
public class testing {
public static void main(String[] args) {
B b = () -> System.out.println("MyText");
b.somefunction(); //Why do I need to call somefunction()
}
}
If I don't write b.somefunction(); I don't get any output even though the compiler does not give an error.
I don't pass any value to the method so why do I need to call the abstract method?
Is there anyway to skip the abstract method call? If my case was to add or perform some calculations, then I can understand that I need to pass some values in method, but in the above scenario I am just printing the value.
If you want the output to print when your program runs, write:
public class testing {
public static void main(String[] args) {
System.out.println("MyText");
}
}
If you want the output to print when some other function runs, then you might use a lambda:
class Testing {
public static void main(String[] args) {
runn(() -> System.out.println("MyText"), 10);
}
static runn(Runnable task, int times) {
for (int i = 0; i < times; ++i) {
task.run();
}
}
}
Lambdas exist to make it easy to specify a function whose execution you want to delegate to another entity. When the lambda is invoked, its arguments, and the treatment of its result are up to someone else.
A functional interface serves to provide a way
to define what is to be performed on a given call and
to define when it is to be called.
Normally, you'd define a "lambda object" as you did and then pass it to somewhere else to tell what to do under a certain circumstance. If you want to see it this way, it is a kind of callback.
The entity where you pass this object calls/uses it when it sees time to do so, or you do it yourself, as you do it in your example.

Restrict lambdas on certain interfaces

Assuming I have a couple of interfaces with exactly one abstract method. Having these interfaces, I can declare lambdas with it:
interface A {
int c();
}
interface B {
int c();
}
public class Main {
public static void main(String... args) {
A a = () -> 42;
B b = () -> 42;
}
}
Short question: is there some trick or hack to restrict using interface A for lambdas and fail the build on attempt to do so? Any hint, dirty or not, is welcome (by 'dirty' I mean hacks on compilation/bytecode level - something which won't affect sources and, preferably, public contracts).
Long story: for some interfaces implementors I consider defining equals/hashCode as a part of the contract. Also, I generate equals/hashCode automatically for them at build time.
In this context, lambdas are troublemakers. For ordinary and anonymous implementors of interface A I can find a .class file and instrument its bytecode at build time. For lambdas there is VM-anonymous class, produced at run time. Affecting such class seems impossible at build time, so I need to at least prohibit such occasions for a specific set of interfaces.
Please take a look at my solution on that:
package com.example.demo;
public class LambdaDemo {
public static void main(String[] args) {
//doesn't compile
//LambdaRestrictedInterface x = () -> {};
LambdaRestrictedInterface y = new Test();
y.print();
}
private static class Test implements LambdaRestrictedInterface {
#Override
public void print() {
System.out.println("print");
}
}
public interface MyInterface {
void print();
}
public interface LambdaRestrictedInterface extends MyInterface {
#Override
default void print() {
//hack prevents lambda instantiating
}
}
}
https://dumpz.org/2708733/
Idea is to override parent interface with default impl
Edit from originator: After some consideration, I decided to accept this answer, (since it suited my needs the best and is rather cheap to implement) with some formal additions. In fact, it was realized that the minimal instrumentation which is enough to prevent interface being used as lambda-type is to just add default implementation to its abstract method.
From playing around a bit, it looks like the desc field of the invokedynamic call contains the interface that's being implemented. For instance, when I created a simple () -> {} Runnable and then passed it through ASM's Bytecode Outline plugin, the "ASM-ified" call looked like:
mv.visitInvokeDynamicInsn("run", "()Ljava/lang/Runnable;", new Handle...
So if you're able to do the build-time hack on the call site (as opposed to somehow marking the annotation itself as non-lambda-able, which I don't think you can do) then you should be able to first compile a set of disallowed interfaces, and then check the invokedynamic's desc against that set.

How to use consumer and supplier instead Reflection in java 8

I have a two simple class and use reflection pattern for invoke method.
I want to write module programming.
Suppose we have a table in database that keep modules name:
Id moduleName methodName ClassName active
1 sample a com.examle.sample true
2 SMS sendSMS com.example.SMS false
3 Email sendEmail com.example.Email false
... ... ... ...
When active is true the module must be activated.So when i write a program and compile that, i do not like again compile whole MyApp. So i use reflection pattern to invoke module. please see the codes.
public class Sample {
public void a() {
System.out.println("Call Method a");
}
}
public class SMS {
public void sendSMS(String str) {
System.out.println("send SMS ok");
}
}
public class Email {
public void sendEmail(String str) {
System.out.println("send Email ok");
}
}
public class SampleMainClass {
public static void main(String[] args) {
//coonect to database and fetch all record in tables
while(record.next){
if (record.getActive()){
Object o = Class.forName(record.getClssName()).newInstance() ;
Method method = o.getClass().getDeclaredMethod(record.getMethodName());
method.invoke(o);
}
}
}
output
Call Method a
So i heard in the java 8, reflection pattern is deprecate and instead that we can use consumer and supplier.
How to use consumer and supplier instead Reflection in java 8?
Thanks.
public class Q42339586 {
static class Sample {
void a() { System.out.println("a() called"); }
void b() { System.out.println("b() called"); }
}
static <T> void createInstanceAndCallMethod(
Supplier<T> instanceSupplier, Consumer<T> methodCaller) {
T o = instanceSupplier.get();
methodCaller.accept(o);
}
public static void main(String[] args) {
createInstanceAndCallMethodJava8(Sample::new, Sample::a);
}
}
Here, createInstanceAndCallMethod does what is done in your main() Method but it accepts parameters instead.
A Supplier is used to create a new instance and a Consumer is used to call a particular method on that instance. In the example both method references are passed as both parameters. Instead, you could also use lambda expressions and write () -> new Sample() and o -> o.a() instead. Please refer to this official tutorial part for more information.
The advantages over reflection are obvious:
You cannot ask createInstanceAndCallMethod to create an instance of a class that doesn't exist.
You cannot ask createInstanceAndCallMethod to call a method that doesn't exist in a particular class.
As a result of both you don't have to deal with any checked Exception.
Of course this does only work when at some place in the code the actual class and method are known, e.g. it's not possible to read class and method name from a properties file and then use Java 8 mechanisms to safely create an instance and call a particular method.
Consumer and Supplier are functional interfaces and they do not refer to reflection.
It's different things.
So i heard in the java 8, reflection pattern is deprecate and instead that we can use consumer and supplier.
Wrong information.

How to access method from two classes which do not share an interface?

I am creating a java library that will access web services, but the library will be called in different platforms, so we are using ksoap2 and ksoap2-android to generate helper classes for the different platforms. The problem is that we then have two sets of generated classes/methods whose signatures are equivalent, but which do not overtly share a Java Interface - so I can't figure a way to call them from my main code.
A simplified example:
//generated for Android
class A {
public String sayHi() {
return "Hi A";
}
}
//generated for j2se
class B {
public String sayHi() {
return "Hi B";
}
}
//main code - don't know how to do this
XXX talker = TalkerFactory.getInstance()
String greeting = talker.sayHi()
Of course, that last part is pseudo-code. Specifically, how can I call sayHi() on an instance of an object which I don't know the type of at compile time, and which does not conform to a specific interface? My hope is that there is some way to do this without hand editing all of the generated classes to add an "implements iTalker".
The straightforward way is to use an adapter.
interface Hi {
void sayHi();
}
public static Hi asHi(final A target) {
return new Hi() { public void sayHi() { // More concise from Java SE 8...
target.sayHi();
}};
}
public static Hi asHi(final B target) {
return new Hi() { public void sayHi() { // More concise from Java SE 8...
target.sayHi();
}};
}
In some circumstance it may be possible, but probably a bad idea and certainly less flexible, to subclass and add in the interface.
public class HiA extends A implements Hi {
}
public class HiB extends B implements Hi {
}

Saving blocks of code in variables

In Objective C you have a function blocks.
You can save blocks of code in a variable and pass them as parameters.
[objects enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
// Enumerating all the objects of an array
}];
In my game I have a MenuScene with MenuSceneItems.
In this case I would want to pass the code they should execute if they have been clicked.
This would eliminate the need of a switch statement.
Is there a way to to is there a way to do this or something similar in Java?
In Java you can't have anonymous function blocks you need to use an anonymous class:
menuScene.executeWhenClicked(new Runnable() {
public void run() {
// do something
}
});
This sounds like straightforward polymorphism e.g.
public interface Action {
void doSomethingWhenPressed();
}
and just implement an object that implements the above interface. Pass that as an argument.
You'd likely do this using an anonymous class e.g.
// this method takes an 'Action' as an argument
passToMethod(new Action() {
public void doSomethingWhenPressed() {
System.out.println("Pressed!");
}
});
In java, you create an object (it doesn't have to have an explicit class type) that extends Runnable, and put the block of code in the run method. Like so
Runnable myDelayedBlockOfCode = new Runnable() {
public void run() {
doA();
doB();
doC();
}
};
If working with a framework, look closer for a framework specific interface that allows you to place such blocks of code into whatever the framework will call.

Categories