I'm working on a project that makes really heavy use of the javax.script.* packages. I have a situation where I would like to create JavaScript objects that extend an Abstract Java Class, much like you can use Invocable.getInterface to make JavaScript objects that implement Java interfaces. Is this possible? And, if so, how do you do it?
Yes, you can; previous poster is wrong. See the documentation for JavaAdapter.
Unless you want to go the route of generating bytecode at runtime (using BCEL as below) then no. You can do it with interfaces using proxy classes but there is no equivalent for abstract classes.
If you really want to try BCEL, your best strategy is to do this:
Write a method that uses BCEL to generate a byte[] of bytecode for a new class that extends the abstract class and delegates every abstract method to JavaScript.
Define a naming convention that relates abstract classes to the wrapper, e.g. foo.MyAbstractClass corresponds to foo.MyAbstractClassDynamicLangWrapper.
Roll a ClassLoader that implements findClass to recognize that naming convention and to generate the class bytes and calls defineClass
Make sure your scripting language uses your custom classloader to resolve class names in scripts. I think in Rhino you use setApplicationClassLoader but I'm not sure.
Related
I'd like to declare a variable that could be an object of x.y.z.z.y.Foo, x.y.z.z.y.Bar or x.y.z.z.y.Baz. If these classes were maintained by me, I'd create a class (e.g. x.y.z.z.y.Nice), so my variable would be declared as Nice variable. But the x.y.z.z.y package is a 3rd-party library (https://github.com/kubernetes-client/java, to be exact), so I can't make this library's classes implementing the Nice interface.
Is there a way to define some pseudo-interface/-class to have been assured that the variable could hold an object of certain classes of a 3rd-party library?
Thanks in advance!
I'd probably write a facade class to encapsulate the use of the 3rd-party package. Then that facade class and your other classes can all implement the Nice interface.
(A side benefit is that if you decide to switch to using some other 3rd-party package instead of the current one, you only have to change the facade class, not everything that uses it.)
About how to name a class how Helper or Utils it is clearly explained in:
What are the differences between Helper and Utility classes?
It such as: XHelper or XUtils. I did do a research and I got the following results:
About Utils we can see for example in Spring Framework through:
AnnotatedElementUtils
AnnotationConfigContextLoaderUtils
AopConfigUtils
And in Java too:
BasicGraphicsUtils
SynthGraphicsUtils (it is an exception to the rule, because all its methods are not static)
Same about Helper we can see for example in Spring Framework through:
JsonExpectationsHelper
LocalizedResourceHelper
ReflectionHelper (it is an exception to the rule, because all its methods are static)
In Java is confuse in someway because the are many Helper classes where the methods are declared how static. Something I had observed is that practically all of them are within the org.omg package and not something like java.xxx or javax.yyy
Returning to the point
But what about Support? Such as XSupport.
It seems to be very similar to either Helper or Utils
There are many classes with this pattern through Java such as:
BeanContextChildSupport
BeanContextServicesSupport
CompositeDataSupport
DescriptorSupport
and Spring Framework
ViewResolverSupport
WebApplicationObjectSupport
WebMvcConfigurationSupport
So what is the rule(s) to apply definitely the Support term for a class name?
(but of course, taking in consideration the two other terms)
Utils
Set of static utility methods (stateless) of some type e.g. StringUtils (Apache Commons Lang).
Note there is a more neat convention for such a class: Strings, Iterables, Lists (Guava), which is also used in Java (Arrays, Collections).
Helper
Instantiable (stateful) class which helps to build functionality of particular type i.e. simplifies work with given type.
Support
Sounds very similar to Helper, but if you consider ConfigurationSupport it feels like more than just helper, which makes things easier i.e. contains something that is required/needed to get things work.
From the accepted answer :
A Utility class can be understood to only have static methods and be stateless. You would not create an instance of such a class.
A Helper can be a utility class or it can be stateful or require an instance be created. I would avoid this if possible.
Added how I understood about the support classes:
A Support class could be understood as the core components required to support a feature/functionality (like java.lang primitive classes and object classes) which provide the base framework can be categorized as support classes
I am wondering about replacing Java's 'extends' keyword somehow for dynamically extending a class based on a parameter(file, environment variable, db...basically anything). Is this even possible because playing with class loaders or calling constructors does not achieve this. I am not asking "should I use interface or superclass hierarchy" rather what is extending really mean under the hood in JAVA because there aren't any good description about it just the good old inheritance jargon:
https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
The only way to "replace the extends keyword" is to dynamically create classes at runtime, which is entirely possible but non-trivial. Vert.x is a good example of a project that makes extensive use of dynamically-generated classes.
Java wasn't designed as a dynamic language in that sense. There are several dynamic languages out there (some of which can run on the JVM), such as JavaScript.
rather what is extending really mean under the hood...
Without getting into a long treatise on OOP, when you say Derived extends Base, it means that Derived inherits both the public and protected API of Base (which it can then add to) and also the implementation of that API. It means that code expecting to see a Base instance can accept a Derived instance, because Derived "is a" Base. This link is created a compile-time. At runtime, instantiating an instance of Derived involves all of the plumbing that instantiating a Base instance involves, plus then the added plumbing for Derived.
To achieve this you need to maintain various versions of a class based on the condition and you have to customise class loader as well because at a point when you find that you have to load a particular instance, you need to load that class which is not loaded by default class loader on JVM startup.
Its better to maintain multiple versions of the class and let JVM do its job which it does perfectly.
You can't do that with a language like Java. The information about "inheritance" is not only used by the compiler, it is also "hard-baked" into the compiled byte code.
If you really want to such kind of "dynamic" meta programming; you are better of using languages that allow you to do so; instead of "violating" a language that was never intended for such kind of usage.
To use some stupid comparison: just because you happen to know "screws" and "hammer" ... you wouldn't start to use a hammer to get those screws into the wall, would you? Instead, you would be looking for a tool that works better with "screws" than a hammer.
If you still want your code to run within a JVM; you might consider languages like jython or jruby.
Every other class in Java inherits from the Object class.
Is it possible to add a second, completely separate, class hierarchy in Java based around my own FastObject class?
My original goal in doing so was to create smaller, faster objects with less functionality specifically designed for certain algorithms. But let me be clear, I am not interested in whether or not this is a "good idea". I just want to know if it is possible; I have not been able to find a way to do so. Would it require a change to the JVM? New boot classpath functionality? Is the real solution to ignore Object and look at replacing java.lang.Class? Would using a direct Java compiler instead of a VM make my job any easier?
To be clear, I don't just want to edit the root Object class. That would require potentially re-writing the entire Java library. I don't want to replace the current hierarchy, I just want to create a separate one I can use in the same code.
No, this is not possible.
All created classes extend another class, either explicitly or implicitly. If you create a class and explicitly define which class it extends, then it extends that class. If not, then it implicitly extends Object. There is no way around this, just as there is no way to overload operators or anything of that sort. It is a fundamental design decision of the Java programming language.
All classes extend Object. The only things that don't are primitive types. The exception to this is Object itself, of course, which does not extend itself.
It may be possible for you to inject your own Object implementation by mucking with the boot classpath. However, I don't think there is any way to use a base object other than Object. You could try some byte code manipulation, but it is entirely possible that your modified class will be rejected by the class loader.
Is there a way to create Java classes # at runtime
(classes methods n variables), with using Java reflection API
You can't do that using reflection. You need a bytecode manipulation library, like Jakarta BCEL.
The standard Java API provides a set of static methods, that allows you to dynamically create a class that implements one (or many) interfaces.
Those methods are part of the class java.lang.reflect.Proxy.
What do you require this for?
Interpreting the question in a very loose manor I can think of four likely options.
If you have a class that you add something too you might find that Aspect-oriented programming is what you are really after.
If you have an interface that you want to dynamically implement (as posted by barjak) what you want is java.lang.reflect.Proxy. This does not let create "code" at runtime but rather allows you link existing code to to a interface.
Finally (at three I know) you have actually building random classes at runtime. This you will need something like cglib or BCEL. While there are cases when this is required it is IMO rare.
One other option is that you don't really need runtime but rather build time. In this case you might be able to use annotations and apt (Java 5) / Processor (Java 6).
Sure there is. You need a java.lang.Class instance initially, for the target class you wish to create. Depending on your structure, this might either be passed in by a caller (if they're supplying the concrete class they want created), or you can statically access the class variable (e.g. MyFooImpl.class).
The simplest way is to call Class.newInstance(). This invokes the default, no-arg constructor (assuming there is one for the class; if not it throws an exception).
If you need to invoke a particular constructor with some argument, you need to call Class.getConstructor() to get a Constructor instance, which you can then call newInstance on.
In all cases you'll need to deal with reflection exceptions that you wouldn't get if invoking the constructor directly.
Big edit: I assume your question was about creating instances of a class via reflection. However I'm beginning to think that you're asking about defining new classes through at runtime. If so, then reflection won't help you here - you'd need to invoke a compiler programatically, which I believe can be done but I'm not 100% on the details. I think you'd also have to go through some hoops to get the ClassLoader to pick up your new class too.
You can create the source code string and compile it to an class file using Janino.
As people have already mentioned, there's no way of creating new classes at runtime using reflection. One library that I know is used by different mocking libraries and the likes is cglib.
you can use javassist. here is sudo code
javassist.ClassPool pool = new ClassPool(true);
CtClass bclass = pool.makeClass("brandnewclass);
bclass.addConstructor(CtNewConstructor.defaultConstructor(bclass));
CtClass[] fieldclasses = new CtClass[fields.length];
CtClass serClass = pool.get(Serializable.class.getName());
bclass.addInterface(serClass);
Class clazz = pool.loadClass("className");
obj = clazz.newInstance();
Use reflection to extract values from an existing class and assign values to new class.
hope this helps.
Gopi