How to inherit/replace a java final class? - java

I'm making a tool to perform several checks in runtime (this is going to be runned in the CI server) and one of the things that I need it's too change implementations of some classes to give the data that I need (basically, I need to know when some specific changes happen in some classes).
This is an OSGi application (I don't know if that's the right name) and I'm using AspectJ to make this information capturing, but AspectJ doesn't change JDK classes and, while I can solve my problem with some classes like LinkedList (not final class with non-final methods), I have to do the same with classes like StringTokenizer or StringBuilder (which I can't inherit or inject code with aspects).
After a few searches I have many questions about HotSwap, custom classloaders and a few other solutions that I've found and I don't know if they're going to satisfy my needs.
I'm using Eclipse Indigo (if it's a solution that will just work on the IDE will be fine too) with Java 6

Look at Apache BCEL to manipulate the bytecode of Java Final classes in a convenient way. This way, you can create your own custom classloader, load the class, manipulate the bytecode to include your own checks and then pass the modified class on to your runtime program.
http://commons.apache.org/proper/commons-bcel/

Related

Find out used classes and methods from Java source code

For Java source files, I would like to find out:
Which classes use which other classes (fully qualified names)?
Which methods call which other methods (fully qualified names)?
What would be a reasonable way to achieve that?
EDIT:
To clarify: I want a list of source code files as input. The output should be (as specified above) which class uses which other class and which method calls which other method. I do not want to inspect other loaded classes at runtime, like when using reflection.
You need to use static analysis tool as STAN standalone mode:
The standalone application is targeted to architects and project managers who are typically not using the IDE.
Or JArchitect (available also using command line)
JArchitect is a powerful tool for static code analysis. It can provide a lot of insight into complex code bases. Using custom code queries you are able to build your own rule sets in a very comfortable way.
In the Class Browser right-click menu, JArchitect proposes to explore the graph of dependencies between members (methods + fields) of a type.
Another option is SourceTrail
The graph visualization provides a quick overview of any class, method, field, etc., of interest and all its relations. The graph is fully interactive. Use it to move through the codebase by focusing on related nodes and edges.
(source: sourcetrail.com)
Unfortunately, reflection doesn't give you all the information you need to do this.
I've done it with ASM (https://asm.ow2.io/).
It provides the ability to walk the byte code of all of your classes using the visitor pattern, including the actual method implementations, from which you can extract the references to other classes.
I'm sorry that I cannot provide the implementation, because it's proprietary.
Note that this works from your .jar files, not your sources. If you really need to work from sources, then have a look at https://github.com/javaparser . Really, though, it's better to use the byte code, since the java language changes frequently, while the byte code specification does not.
I am not sure how to get a listing, but for identifying refactoring opportunities, you might try IntelliJ IDEA. It will dull out the signature line of any methods that are not accessed in the project. It will also detect code segments that are repeated elsewhere in the project, so you can extract common code.

How to use the Java Instrumentation API to reload classes when they change on the the file system?

I don't want to use the URL Classloader to load classes.
I want to implement this myself.
I don't want to use a solution like JRebel (although it's great).
I've got prior experience of JavaAssist, bytecode generation, implementing javaagent class transformers etc.
I would like to write a javaagent which hooks into the classloader or defines it's own system classloader.
I'll store the class files in an in memory cache, and for particular files, periodically reload them from disk.
I'd prefer to do this in a way which doesn't involve continuously polling the file system and manually invalidating specific classes. I'd much rather intercept class loading events.
I last messed around with this stuff 4 years ago, and I'm sure, although my memory may deceive me that it was possible to do, but 8 hours of searching google doesn't present an obvious solution beyond building a patched JVM.
Is this actually possible?
I've created a stub implementation at https://github.com/packetops/poc_agent if anyone's interested in a simple example of javaagent use.
update
Just found this post - I may have been using the wrong approach, I'll investigate further.
It depends on what you want to do. If you want to reload your classes and define new ones, then you are fine with implementing your own classloader, as you already found.
If you want to replace existing classes, things become more "envolved". You can do this by implementing your own tiny Java agent. See the Java documentation, how to do this: http://docs.oracle.com/javase/7/docs/api/java/lang/instrument/package-summary.html
With the instrumentation mechanism you can not freely redefine classes, quote from Instrumentation.redefineClass:
The redefinition may change method bodies, the constant pool and attributes. The redefinition must not add, remove or rename fields or methods, change the signatures of methods, or change inheritance. These restrictions maybe be lifted in future versions. The class file bytes are not checked, verified and installed until after the transformations have been applied, if the resultant bytes are in error this method will throw an exception.
If you want to do more, you need to load it again. This can be done under the same name, by using a different classloader. The previous class definition will be unloaded, if no one else is using it any more. So, you need to reload any class that uses your previous class also. Utlimatly, you end up reinventing something like OSGi. Take a look at: Unloading classes in java?

Splitting my gwt app into specific gwt code and a generic Java project?

I have a gwt project that acts as a semantic engine for other projects.
I recently realized very very little of the code is specific to gwt. Its almost all pretty basic java. In fact, the only things specific to gwt is retrieving files.
So what I would like to do is to separate out the gwt completely so I can use the same basic code for other Java projects - such as Android or Processing apps.
So, "Semantic Core" project could be inherited by GWT,Android and Processing apps and I wont have to maintain separate versions for each.
To do this, however, I need some way for other projects to "give" the Semantic Core project their own file-handleing methods.
My current idea how to do this;
One method I thought how to do this was to have SemanticCore define a Interface for FileManager with a method like;
getFile(String,MyErrorHandler,MySuccessHandler)
And then have the class's for MyErrorHandler and MySuccessHandler defined also in the SemanticCore project, effectively being runnables that take a string as a parameter.
With this Interface defined, other projects (GWT,Android etc) have to define their own class that implements it
eg, GWTFileHandler implements FileManager
Then create a object of this class, and pass it to the SemanticCore;
SemanticCore.setFileManager(new GWTFileHandler());
The semantic core can then use it at its leisure to retrieve files in a way suitable for the platform its on.
Question;
Is this a good way to do it? It seems wrong to me I am creating a new object, when I'll only be using static methods from that class.
Alternatives?
I hope my description is clear. As this all has to be GWT compatible in the "SemanticCore" project, any use of reflections is ruled out.
Thanks,
The recommended approach IMO is to use Deferred Binding to pick the GWT compatible version of your FileHandler or other GWT specific implementations. Extract the common interface for all versions and in your GWT module file you point to correct GWT implementation.
You can then instantiate your specific implemenation using GWT.create :
MyInterface implemenation = GWT.create(MyInterface.class);
more in depth info on the gwtproject site.
Deferred Binding is a technique used by the GWT compiler to create and
select a specific implementation of a class based on a set of
parameters. In essence, deferred binding is the GWT answer to Java
reflection. It allows the GWT developer to produce several variations
of their applications custom to each browser environment and have only
one of them actually downloaded and executed in the browser.

Finding new Java class at runtime

I have a functionality that I wish to provide to a customer for a software mockup that we are preparing - and I want to know if it's
possible
intelligent (a.k.a. not stupid)
the best thing
I want the customer to be able to write a java class that implements my Computable interface and stick it in some predetermined folder. This folder will contain the .java files rather than .class files. Then, at runtime, I want my program to search that folder and extract all of the Computables from that folder and store them in a map from the name of the Computable to the Computable object. The Computable should only have a default constructor and the it interface will only have one method called compute which maps an array of Object to an Object.
The Java Compiler API introduced in Java SE 6 should give you what you need.
You may find Google Reflections useful to find classes implementing/extending a certain interface/superclass in the classpath. It's then as straightforward as
Reflections reflections = new Reflections("my.project.prefix");
Set<Class<? extends SomeClassOrInterface>> subTypes = reflections.getSubTypesOf(SomeClassOrInterface.class);
Then, to test if it indeed has a no-arg default constructor, just check for each if Class#newInstance() doesn't throw any exception.
There are several suggestions provided as answers to this question.
Here too On-the-fly, in-memory java code compilation for Java 5 and Java 6
If it's easy enough to compile at runtime that would be fine.
You can use javax.tools to do the compilation as needed. Create dynamic applications with javax.tools may help, too. It's also possible to do it in memory.
One caveat: using the compiler creates a dependency on the JDK; the JRE alone is insufficient.
take a look: Find Java classes implementing an interface
I think this would be simpler if you allowed your customer to type in a code declaration using something like Groovy, which is Java-ish enough, and easy to execute at runtime from a String value.
It's easy enough to iterate through the list of files in a folder. Someone mentioned that it's possible to call the Java compiler from Java (if you re-distribute the JDK, which I think is a point whose legality needs checking!!) That's much of the battle.
You seem to have a fixed model in your mind where only files fulfilling a certain interface are extracted from the folder. I think this is where your method needs to give a little. The sensible way (IMO) to do this would be to compile all files in that folder, and then with their classes stashed away somewhere, you can load and reflect them and then determine which of them "do" the interface and which don't. Those that don't will have been needlessly loaded into your JVM, but unless it's intentionally very space-wasteful, code you don't execute can't harm your program.
Having determined which ones do the computable thing, you can then store those classes (or instances thereof) in a Collection and do whatever you like with them. You simply ignore the other ones.
You could use BeanShell. This library is small and doesn't require the JDK. It is used in a number of IDE and web servers. The latest version appears to have the support you need loading .java files from the class path. (Still in beta)

Extending or adding new classes at runtime in Java

Is there a way to add (or extend existing) classes at runtime in java. I'm stuck on a problem, in which I have to extend an existing class at runtime and add this to the classpath, so that this new class get picked up.
thanks,
There are a number of ways you could do this.
Compile source code at runtime using the javax.tools package and then load them using a ClassLoader.
If you are writing to interfaces, you can decorate classes with a Proxy.
Take the more complicated route of bytecode manipulation/generation using a technology like BCEL or ASM (the latter has more up-to-date support for language features, like annotations) and then load the class with a ClassLoader.
I imagine there are other options.
You might want to look at BCEL. Without any more information about what you need to do, it's tricky to give a more specific answer.
You should definitely write why you need this feature.
If you attempt to add or replace logic at runtime you might want to have a look at the scripting API and some actual implementations.

Categories

Resources