How to know dynamically if the loaded class is application class? - java

I am in a situation that I want to do some rewriting on loaded,i.e., currently running application class. I do not want to rewrite loaded library class. Thus I need to sort of filter the rewriting based either on the type of the class, being application or none application class, or another way I could do it is by checking the ClassLoader and see if it is of Application Class type.
To give some context let's assume I have the following code
URLClassLoader urlcl = new URLClassLoader(cp);
Class c = urlcl.loadClass(_className);
Assuming that _className is the current running class, that was intercepted by a listener, how can I know if this class c is an application class or not?
Much appreciated!

I'm not entirely sure of what do you mean by application class, but those hints still might be helpful.
You can simply check if one class is subtype of another with:
public static boolean is1stSubTypeOf2nd(Class clazz1, Class clazz2) {
return clazz2.isAssignableFrom(clazz1);
}
If you would like to check if the class belongs to some package (to check if it is the class from standard API, third party library or not), you can use:
public static boolean isInPackage(Class clazz, String packageName) {
return clazz.getPackageName().contains(packageName);
}
Further the standard API is able to provide you an info about all super classes of given class.

Related

Java Application return super class when initialized

Nowadays we are on writing some core application that is all other application will be relying on. Without further due let me explain the logic with some codes,
We used to have a single java file that was 1000+ lines long and each application was having it as class inside, so when there was a change, each application had to edit the java file inside of it or simply fix one and copy to all. This is hard to implement as much as it is hard to maintain. Then we end-up with creating this as a separate application that is divided to smaller part, which is easy to maintain and also a core maybe a dependency to other application so we fix in one place and all other code applications are fixed too.
I've been thinking for a some great structure for this for a while want to use a builder patter for this as below
TheCore theCore = new TheCore().Builder()
.setSomething("params")
.setSomethingElse(true)
.build();
The problem arises now. Like so, I initialized the object but now I'm having access to that objects public class only. This application actually will have many small classes that has public functions that I don't want them to be static methods that can be called everytime. Instead I want those methods to be called only if TheCore class is initilized like;
// doSomething() will be from another class
theCore.doSomething()
There are some ideas I produced like
someOtherClass.doSomething(theCore)
which is injecting the main object as a parameter but still someOtherClass needs to be initialized or even a static method which doesn't make me feel comfortable and right way to that.
Actually I do not care if initializing TheCore would bring me a super object that includes all other classes inside initialized and ready to be accessed after I initialized TheCore. All I want in this structure to have a maintainable separate app and methods avaiable if only the main object which is TheCore is this circumstances is initialized.
What is to right way to achive it? I see that Java does not allow extending multiple classes even it if does, I'm not sure it that is right way...
Thanks.
After spending significant amount of time of thought I ended up that
// doSomething() will be from another class
theCore.doSomething()
is not suitable since many java classes could possibly have identical method names. So...
// doSomething() will be from another class
theCore.someOtherClass.doSomething()
would be a better approach.
To make it easier to understand I'll have to follow a complex path to explain it which is starting from the package classes first.
Think that I have a package named Tools and a class inside SomeFancyTool
main
└─java
└─com
└─<domainName>
├─Tools
| └─SomeFancyTool.java
└─TheCore.java
Now this SomeFancyTool.java must have a default access level which is actually package level access, because I don't want this classes to be accessed directly;
SomeFancyTool.java
package com.<domainName>.Tools
class SomeFancyTool{
public String someStringMethod(){
return "Some string!";
}
public int someIntMethod(){
return 123;
}
public boolean someBooleanMethod(){
return true;
}
}
So now we have the SomeFancyTool.java class but TheCore.java cannot access it since it is accesible through its Tools package only. At this point I think of an Initializer class that is gonna be in the same package, initialize these private classes and return them with a function when called. So initiliazer class would look like this;
ToolsInitializer.java
package com.<domainName>.Tools
public class ToolsInitializer{
private SomeFancyTool someFancyTool = new SomeFancyTool();
public SomeFancyTool getSomeFancyTool(){
return someFancyTool;
}
}
Since ToolsInitializer.java can initialize all functional private classes inside in Tools package and also can return them as objects to outside of the package scope, still we are not able to use these methods as we cannot import com.<domainName>.SomeFancyTool from TheCore.java because it is package wide accessible. I think here we can benefit from implementation of the java interface. A class that is not functional alone, so no problem even if it is accessed since it's methods will be nothing but declarations.
At this point I'll rename SomeFancyTool.java to SomeFancyToolImplementation.java which it will be implementing the interface and call SomeFancyTool.java to the interface itself.
SomeFancyTool.java (now as an interface)
package com.<domainName>.Tools
public interface SomeFancyTool{
public String someStringMethod();
public int someIntMethod();
public boolean someBooleanMethod();
}
and lets rename prior SomeFancyTool.java and implement the interface
SomeFancyToolImplementation.java (renamed)
package com.<domainName>.Tools
class SomeFancyToolImplementation implements SomeFancyTool{
#override
public String someStringMethod(){
return "Some string!";
}
#override
public int someIntMethod(){
return 123;
}
#override
public boolean someBooleanMethod(){
return true;
}
}
Now our structure has become like this with the final edits;
main
└─java
└─com
└─<domainName>
├─Tools
| ├─SomeFancyTool.java
| ├─SomeFancyToolImplementation.java
| └─ToolsInitializer.java
└─TheCore.java
Finally we can use our TheCore.java class to call all initializer classes with their methods to receive all these private classes inside as an object. This will allow external apps to call and initialize TheCore first to be able to access other methods.
TheCore.java
public class TheCore{
private SomeFancyToolImplementation someFancyTool;
public static class Builder{
private SomeFancyToolImplementation someFancyTool;
public Builder(){
ToolsInitializer toolsInitializer = new ToolsInitializer();
someFancyTool = toolsInitializer.getSomeFancyTool();
}
public Builder setSomeValues(){
//some values that is needed.
return this;
}
public Builder setSomeMoreValues(){
//some values that is needed.
return this;
}
public TheCore build(){
TheCore theCore = new TheCore();
theCore.someFancyTool = someFancyTool;
return theCore;
}
}
}
All Done and it is ready to use. Now the functional package classes and its methods that it relying on if TheCore is initialized or not, cannot be accessed with out TheCore. And simple usage of this Library from a 3rd Party app would simply be;
3rd Party App
TheCore theCore = new TheCore.Builder()
.setSomeValues("Some Values")
.setMoreSomeValues("Some More Values")
.build();
theCore.someFancyTool.someStringMethod();
Note: Note that a the ToolsInitializer.java is still accessible and could be used the get private method without first calling TheCore but we can always set a checker inside getSomeFancyTool() method to throw error if some prerequisites are not satisfied.
I do not still know if this is a functional structural pattern to use or its just some hard thoughts of mine. And don't know if some pattern is already exist that I just could not see yet but this is the solution I end up with.

How is this interface being instantiated?

This is from the Minecraft server source code, also called the Minecraft Bukkit API, now you know as much as I do.
There is an interface called Server:
public interface Server extends PluginMessegeRecipient {
public String getVersion();
}
PluginMessageRecipient is an interface also.
There is a class called Bukkit that instantiates Server:
public final class Bukkit {
private static Server server;
}
Inside methods in the Bucket class they invoke methods from the server object. For example:
server.getVersion();
The thing is, there is no code for getVersion in the Server interface, just a method signature. There is also no code in the PluginMessageRecipient interface nor does it extend anything.
I have read all the questions and answers on SO that say I need an anonymous class or an inner class and this does not seem to fit those solutions.
There is a class called Bucket that instantiates Server:
Actually Bucket doesn't instantiate Server. The class Bucket contains a reference to a Server. You haven't shown how that got set so we don't know the actual class.
However, it is guaranteed that what is assigned to that reference (Bucket.server), assuming it's not null, is a an object of some concrete class that implements Server. That class will provide an implementation of getVersion() and that is what is being called.
Bukkit is just a Modding API. If you want to implement Bukkit, you need to create such an instance yourself and pass it there.
Take for example the unit tests that Bukkit includes:
https://github.com/Bukkit/Bukkit/blob/f210234e59275330f83b994e199c76f6abd41ee7/src/test/java/org/bukkit/TestServer.java#L77
A real implementation that allows you to run a Bukkit server is Spigot.
If I recall correctly, the particular concrete class that's being selected is determined at runtime via reflection. Because Minecraft is not open source, all the developers have are the obfuscated compiled class files to work with.
The code searches through each class file within the minecraft jar, searching for a class that matches certain conditions, and then, using a bytecode library, force that class to implement that interface.
For example, let's say that the following (obfuscated) class was the real Server class within the Minecraft code
class a {
String x_x317() {
return q_q98;
}
static a a_a1;
static String q_q98 = "1.9.4";
}
In this case, the method x_x317 returns the version string. The tool that allows them too hook into this class might do it based on the following conditions:
The class has default access
The class has only one default access static reference to itself
The class has only one default access static String field.
The class has a single method, that has default access, that returns String, and the returned value is the FieldRef found in 3.
This generally returns only one class. In the case that multiple are returned (usually in the dev phase of the new Bukkit version), they get more specific with their conditions to ensure that they only get the right class returned. They do this for every field, class, and method they need to identify.
Since they now know which exact class is the Server class, they can go ahead and make changes to it. First they would need to implement the interface
class a implements org.bukkit.Server
And then implement the method
class a implements org.bukkit.Server {
String x_x317() {
return q_q98;
}
public String getVersionNumber() {
return x_x317();
}
static a a_a1;
static String q_q98 = "1.9.4";
}
Now, we have a class that conforms to the Bukkit API.
When they need to instantiate that class, they just do something along the lines of
Server server = findAndTransformServerClassFromMinecraftJar();
// ...
Server findAndTransformServerClassFromMinecraftJar() {
// load classes from jar
// map them to the appropriate interfaces
// transform and hook the required classes and methods
Class<?> serverClass = doTheFirstThreeSteps();
return (Server) serverClass.newInstance();
}

Class & ClassLoader

I have a Custom Classloader : CustomClassLoader(extends ClassLoader)
I have a class : IntegerPrint
I load my class with my Custom ClassLoader. I was expecting SOPs in the below code to return the same value. But the first SOP prints "sun.misc.Launcher$AppClassLoader#.." & second SOP prints "CustomClassLoader#.."
Why it happens so? Please advise.
public class IntegerPrinterTest {
public static void main(String[] args) throws Exception {
CustomClassLoader loader = new CustomClassLoader(IntegerPrinterTest.class.getClassLoader());
Class<?> clazz = loader.loadClass("IntegerPrinter");
System.out.println(IntegerPrinter.class.getClassLoader());
System.out.println(clazz.getClassLoader());
}
}
What did you expect?
In
System.out.println(IntegerPrinter.class.getClassLoader());
you create a
Class<IntegerPrint>
object, and surely, its class (Class) must have been loaded by some class loader. It takes no genius to imagine that Class must have been loaded very early, even before your code even gains control.
Please run your example with
java -verbose:class ....
to see which classes are laoded in what order.
The first call:
IntegerPrinter.class.getClassLoader()
Will actually do:
IntegerPrinterTest.class.getClassLoader().loadClass("IntegerPrinter")
So it totally ignores your custom classloader.
In other words: your own classloader is not actually used for any objects you create using native calls like "new" etc. To do that it should be responsible for loading the IntegerPrinter class as well.
It is rather circumspect (and in general useless) to do it in the same class but you could do:
Class<?> clazz = loader.loadClass("IntegerPrinterTest");
clazz.getMethod("main").invoke(null);
(note this code is not tested but should approximate something that works)

GroovyClassLoader - adding parsed classes to classpath

I've got a library that allows clients to provide a list of text files, each of which contains groovy code for a class that extends java class Z. For instance file 'A.groovy' contains
package com.mypkg;
public class A extends Z {
#Override
public void someMethod() {
// do something A-ish
}
}
etc.
The library compiles each of these and (in this case) would return to the clients an instance of type Z.
My issue comes when a client needs something like this:
package com.mypkg;
public class B extends A { // extends A!
#Override
public void someMethod() {
// do something B-ish instead of A-ish
}
}
where B extends A, and class A was parsed before class B.
The issue is that the GroovyClassLoader can't seem to find class A, even though it just parsed A. Here's the code that compiles the scripts and creates the instances:
for (String fileName : listOfScriptFiles) {
InputStream in = getInputStreamFromFile(fileName);
CompilerConfiguration compConfig = new CompilerConfiguration();
GroovyClassLoader classLoader = new GroovyClassLoader(Thread.currentThread()
.getContextClassLoader(), compConfig);
Z service = null;
Class clazz = classLoader.parseClass(in);
service = (Z) clazz.newInstance();
return service;
}
Is there a way to 'register' class A with the runtime so that when Groovy tries to compile class B it will not complain that class A doesn't exist?
UPDATE
I was actually able to solve this by instantiating the GroovyClassLoader outside the loop that iterates through the client's code list, so the classloader that parses A is the same that parses B.
The question still stands, though, because I could envision a case where in one part of someone's code they parse A, and then in a completely different part, where the same classloader is unavailable, they parse B.
In my experience with the Groovy classloader (which is similar in behavior with Ant and beanshell's classloader in this respect) , you have to decide up front whether you are going to use the default system classloader, in which case you would build the classpath into the command that launches the Groovy script, OR on the other hand, you specify ONLY the groovy jar on the command line classpath and then you dynamically add classes at the beginning of your Groovy script on the custom classloader.
You aren't providing much information in your question, but my guess is that you put class "A" on the classpath before you launched the script and then your trying to load class "B" dynamically. That wouldn't work as far as I know.
NOTE: I myself have been trying to figure out how to do this kind of thing. It seems it would be possible but I still haven't figured it out.

Configuration class - best practice with Guice

Background: I'm using Google Guice and so it's easier to pass through the configuration class but I think this is not the best way.
I have a configuration class which stores some paths:
class Configuration{
String getHomePath();
String getUserPath();
}
Also I have a class "a" which needs the "homepath" and a class "b" which needs the "userpath".
Is it better to pass the configuration class through the constructor of class a and b or only pass through the specific path?
If you're really using Guice correctly all your configuration like this should appear in modules' configure method. So:
Remove the configuration class.
Create annotation classes, probably called HomePath and UserPath.
Where class a uses getHomePath() replace that with a String field member named homePath.
Where class b uses getUserPath() replace that with a String field member named userPath.
Modify the class a and b constructors to be #Inject annotated (should already be) and take in a String parameter, respectively annotated with #HomePath and #UserPath and assign the String field member that injected value.
Create bindings in your module's configure method use .annotatedWith() which define correct values; if they're only available at run time, bind a provider.
E.G.
class a {
private String homePath;
#Inject
public a(#HomePath String homePath) {
this.homePath = homePath;
}
public String tellMeAboutHome() {
return "We live in a nice home called " + homePath;
}
}
class customModule extends AbstractModule {
public static final String userPath = "/home/rafael";
public void configure() {
bind(String.class).annotatedWith(HomePath.class).to("/home/");
bind(String.class).annotatedWith(UserPath.class).to(userPath);
}
}
If creating annotations is too much work for you, use the #Named annotation Guice ships with.
There's no single answer to your question, there are only options to choose from, based on your specific situation.
If you know your Configuration class is going to grow AND if it's likely for your A and B classes will use more from it, then pass the whole Configuration object to their constructors. NB: I know this is against the YAGNI principle but sometimes you may know you're gonna need it ;-)
Otherwise, you can consider using #Named injection of your paths so that you reduce A and B classes dependencies to their minimum, which is a good design practice.
The general rule is code to make the dependency graph (which classes know about or depend on other classes/ interfaces) as simple, regular and fixed as possible.
If not passing the Configuration class makes a or b have zero dependencies on on user-written classes, or is necessary to avoid a dependency loop, then use the individual path strings. Otherwise, if it makes more sense to say 'this class has access to configuration info, in a way that may change in the future', pass the class.
I'd avoid the singleton approach, especially if you already have Guice set up.

Categories

Resources