i would like to know if it is possible to somehow read data from a text file and use it to tell java what libaries to import. I dont think its possible in java but what about groovy?
With groovy 1.8, it is possible to dynamically add imports to a script executed with GroovyShell. In particular, take a look at org.codehaus.groovy.control.customizers.ImportCustomizer. There's a good example of how to use this here: http://mrhaki.blogspot.com/2011/06/groovy-goodness-add-imports.html.
You can't totally avoid having 'import' statements, but it is an important part of many implementations of dependency injection that the actual dependencies are defined in a config file (ie. external text) and this information is loaded at runtime.
Groovy has a "import handler", class (interface to be true) GroovyResourceLoader, a kind of event is fired for every import required by "main" source. Is works in cooperation with GroovyClassLoader and maybe not with GroovyShell. I understand that my answer is in different area that "automatically add some hidden imports" - I speak about "classic imports".
Related
I see lot of references to javax.lang.model as being the api for parsing java files and it seems it'll suffice for what I want to do. But I can't find any examples of using the classes in it starting with opening a .java file. The only vague reference I have found are about writing a compiler plugin and invoking your code using javac.
Is that the only way to use this api? Isn't it possible to simply open a file and get the instances of classes from javax.lang.model.element with your own main()? Would anyone be able to point me to working examples of this nature?
The javax.lang.model, javax.lang.model.element, javax.lang.model.element.type, and javax.model.element.util packages are intended for use in annotation processors (javax.annotation.processing.Processor), which are the compiler plug-ins that you mentioned. There is a compiler API that you can use to compile and analyze classes at run-time. You can use javax.tools.ToolProvider.getSystemJavaCompiler() which returns a javax.tools.JavaCompiler class. It has an interface to compile .java files and to run annotation processors against them. For more information check out JavaCompiler#getTask
I've got a question on how to add a jar file with code.
The situation is that I want to allow the customers to choose themselves, which database should be connected. Therefore, I'd like to give them the opportunity to load a custoom *.jar into the running software (similar to Add external library in eclipse).
Is there a way how I can manage that? I was trying kind of
import System.getProperty("java.io.tmpdir") + "\\dbdriver.jar";
java.io.tmpdir\dbdriver.jar would be the file, where custom jar-library-imports will be stored by my code. But eclipse didn't seem to like it.
Do you have any idea?
You'll need to read up on Classloaders and Reflection in order to get an understanding of how this works.
This is a problem of loading jars at runtime.
Please take a look at the following link which is pretty similar to what you're looking for.
Loading jars at runtime
If this is what you are trying to accomplish in a .java file it is not correct, you cannot reference a jar file directly in a java file, you can just import single classes or a group of classes using wildcard '*'.
The best approach, to my knowledge, here would be to install an ORM library and then decide with the client what his choice for "more than one" RDBMS would be.
is there any way to do the following. so i have a project.jar file, inside it i need to modify the string passed to some method of let's say classA.class. for example, let's say this classA.class has a method named
change(String a, String b)
what i all want is to do the following as the first line of the code inside this method as follows:
a = a + "hi";
i want to modify the .class file directly, without needing to recompile everything again. then after that i would update the jar file with the new class file. is it possible? if yes can anyone show an example? thanks a lot in advance!
Yes it's possible with byte code editors. Commonly you can use aspectj together with compile time weaving to modify a class file. You can also use libraries such as BCEL, cglib etc.
However, for the use case you are describing you typically don't need to edit a class file. You can just wrap your object in a proxy or modify it's behaviour using AoP style of programming (as supported by e.g., aspectj)
There are tools to manipulate byte code dynamically, such as ASM: http://asm.ow2.org/
another way could be instrumentation. when you are loading the class you could manipulate the bytecode before using it. there are some good libraries for this, for example javassist from jboss. i think aspectJ works similar.
but why you want to change the bytecode, compile it and add it to a jar file again? are you needing the source code? perhaps you could use some de-compiler to get the source code, if you need it. a good tool is http://java.decompiler.free.fr/.
Is there a way to modify .class files in order to add Java annotations to certain methods? Basically I want to traverse methods of each class file in a jar file and annotate certain ones. Note that this is not at run-time while using the jar file. Rather, after I'm done I want to have modified class files with the annotations.
I do have access to the source code, so if there's an automatic source code modifier, that would work as well...
I'm assuming I'll need a tool such as Javassist or ASM. If so, which one should I use and how would I go about it?
Actually, this is a classic use case for AspectJ:
declare #method : public * BankAccount+.*(..) : #Secured(role="supervisor")
While I will grant you that direct byte code manipulation is more powerful, AspectJ is much more user-friendly, and it immediately gives you compiler warnings when you are doing something wrong.
Also, if you use Load Time Weaving, you can leave the original library jar unchanged, because the weaving happens at class-load time.
Reference:
Declare Annotation
AspectJ in Action (book)
Googling for an hour or so turned this article up which seems to completely answer my question: use ASM. To write class files using the changed bytecode, use ClassWriter.
Well, time to get to work then, I guess. :)
I'm looking for some ideas on how to compile Java code with some other pieces of code missing (method calls). I am fully aware that javac will not allow you to compile Java files if cannot find all dependencies. But maybe there is some way how to bypass it, something like force compile.
My bytecode knowledge is not so good but I think some method invoke is just full package definition of class and method name with parameters. So if compiler just puts this data to class file and assume in running process dependency will be available (if not simple NoSuchMethodExp).
Only workaround so far I found is to create empty missing class files with empty methods to "cheat" compiler. Works perfectly but there should be easier way :)
Any ideas?
Use Interfaces.
Create the interfaces that have the methods you need. At runtime, inject (Spring, Guice, etc.) or generate (cglib ...) classes that implement the interface.
If you're modifying a jar, you can extract the class files you are not modifying to another directory and include that in the classpath. That way they will be available to the compiler.
Bad luck! Probably all you can do is to create mock objects for missing parts of code just to compile your code (empty methods, so the compiler can find it).
Another question - if you miss some classes, how will you execute that code?
UPDATED according to information provided:
Well, there is another option to modify classes in jar, you can use AOP, and to make it done read about AspectJ - actually for me this is the easiest option (typically you need to spend time mocking objects, writing empty methods, so I would contribute that time to study new technology, which will help you many times ;)
And btw the easiest way to implement it, if you use Eclipse, is:
install AJDT
create aspect project
create aspect which modifies code (depending on what you need to change)
add jar file you want to modify
immediately get modified code in
another already packed jar file
Sounds magically :)
In this case you don't need any dependencies in classpath, except for libraries which are needed for new code you add!
Methods aren't dependencies. They are part of the class definition. The only places the java runtime looks for method definitions is in the class def that was compiled at compile time and in its parent classes. If you're problem is that a super class is incomplete, I don't think I can help you.
If not, you could define some of these methods as abstract and than have a child class implement them.
What kind of code is missing? Normally this happens if you refer to libraries your compiler can't find. Maybe you simply need to extend the classpath the compiler is searching for classes.
If you really refer to code that is not available yet you need to implement at least those methods you refer to. But that sounds strange... maybe you can clear things up.