I realize that this is not possible since Android doesnt have a JVM but is there a work around to this problem? I need to perform a byte code injection operation for an Android application. Any suggestions?
You can't directly inject bytecode into already loaded classes/methods. However, you can dynamically create new classes, write them to a dex file, and then dynamically load them
See this blog post for more information on dynamic loading of classes from a dex file on disk.
In order to dynamically create a new dex file, you might look at using the dexlib component that is part of the smali/baksmali codebase, which is a general purpose library for reading/writing dex files.
Or, alternatively, you could include smali in your application and generate your classes in the smali assembly format and use smali directly to assemble them into a new dex file.
Code injection is possible in Android, please take a look on Disabler project hosted on Github.
Disabler allows to optimize, trace and modify Android project on the fly using code injection into existing project. Code is injected on the fly, no need to modify old functionality to add logging/profiling or disable portion of the flow.
Main functionality of the tool:
trace: entering/exiting to/from method, collecting parameters and exiting value)
profile: measuring the frequency and duration of method calls
disable: disabling/skipping part of the program flow by overriding returning value from methods defined by the user
delay: introduce delays in certain sections of the code (i.e. for certain packages)
Under the hood, it uses AspectJ and Eclipse build mechanism (javac is replaced by ajc)
Do you want to inject during runtime or compile time ?
For compile time - there are several very mature solutions for manipulating java source code / bytecode - ASM, java-assist, etc
Specifically for android, try ASMDEX
http://asm.ow2.org/doc/tutorial-asmdex.html
Related
In order to create a valid .class file, every method has to have a full internal name and type descriptors associated with it. When procedurally creating these, is there some sort of lookup table one can use (outside of Java, where a ClassLoader can be used) to get these type descriptors from a method name? For example, how would one go from Scanner.hasNextByte to boolean java.util.Scanner.hasNextByte(int) / boolean java.util.Scanner.hasNextByte() (or even from java.util.Scanner.hasNextByte to boolean java.util.Scanner.hasNextByte(int) / boolean java.util.Scanner.hasNextByte())? The above example has overloading in it, which is another problem a human- but mostly computer-readable declarations file would hopefully address.
I've found many sources of human-readable documentation like https://docs.oracle.com/javase/8/docs/api/index.html containing uses of each method, hyperlinks to other places, etc. but never a simple text file or collection of files containing just declarations in any format. If there's no such file(s) don't worry about it, I can try and scrape some annoying HTML files, but if there is it would save a lot of time. Thanks!
The short answer is No.
There isn't a "header file" containing the class and method signatures for the Java class libraries. The Java tool chain has no need for such a thing. Nor do 3rd-party Java compilers, or compilers for other languages that rely on the Java SE class libraries.
AFAIK, there isn't a 3rd-party tool that builds such a file or an equivalent database or in-memory data structures.
You could create one though.
You could chose an existing Java parsing library, and use it to build parse trees for all of the source files in the class library, and emit the information that you need.
You could potentially create a custom Javadoc "doclet" plugin to emit the information.
Having said that, I don't understand why you would need such a mapping. Surely, your IDE does this already ... and exposes the information via some internal API. And if this is not for an IDE plugin, what it is for?
You commented:
I'm making a compiler for a JVM-based programming language ....
Ah ... so your compiler should do what other compilers do. Get the information from the ".class" file. You can either load the class using a standard or custom class loader, or you can use a library like asm or bcel or javassist ... which can read a ".class" file without loading it.
(I haven't checked, but I think the standard javac compiler uses an internal API to do this.)
Note that your proposed approaches won't work for interfacing with 3rd-party Java libraries where the source code is not available and/or the javadoc is not scrapable.
What about building it from the source files for the standard library?
The Oracle Java 8 API web pages you referenced was created by Javadoc processing of source files for the Java standard library.
If you use an IDE with a debugger, there is a good chance you already have much of the standard library source code downloaded. After all, if you set a break point, and then follow the program step-by-step with "Step into", you can trace the execution of the program into standard library methods. The source files would be part of the JDK.
However, some parts of the standard library source might not be available, due to licensing restrictions.
I'm writing an annotation processor for an Android project and have run into a situation. I would like to process annotated classes from a library module, i.e. app module depends on library module and needs to process annotated classes from the library module.
However, the annotation processor isn't able to "see" the annotations from the dependency, presumably because the code is already compiled. See here for an issue on another library. A demonstration of the problem with my project is on the branch here. The annotations from sample module are processed but the ones from the lib module are not.
This is all well and good and I'd resigned myself to living without this feature, but it turns out the Android data-binding library can process annotations from modules and even third party libraries. This library, for example, provides #BindingAdapter methods that are processed fine by the app.
I played around with setting retention types on the annotations I use to no avail. The only significant difference I can see is that the data-binding processors target methods while my methods target classes (types), but I don't think that should make a difference from the processor. So I'm thinking it might have something to do with the data-binding processor being part of the Android plugin but I'm not sure how that helps here.
Anyone know how this is done?
Android Data Binding can't process annotations on dependencies, either. Instead, it processes the libraries at the compile time of the library and saves the information to an intermediate file as part of its archive (e.g. jar file). It then loads that intermediate file information from the dependency instead of reading the annotations.
If you save the intermediate information as a resource of the jar file dependency, you can pull it from the jar file pretty easily. If I recall correctly, it should be in your class path and you can use the ClassLoader's getResource() method. My memory may be a little stale on this as it doesn't use the jar file to store the intermediate file information any more.
I've written a bunch of android JNI code that I want to make into a library for a customer. Obviously, I don't want the customer to be able to see my JNI code. Is there a way I can include just the so file in a library project for them?
I've tried just using System.loadLibrary(<library>); but I get an Unsatisfied Link Error every time.
One thing that's worked, is I've just compiled my project and deleted all the c files. I'm still able to use the .so file, but if I do a make clean, it deletes my so file and there's no way to recover it without the source.
In short, what I want is to be able to compile an so file on my own, and give it to my customer with some java code that interfaces with it. I don't care if they see the java 'wrapper' source but I don't want them to be able to see the JNI code. I also want them to be able to treat this library as they would any other (ie make cleans don't wreck it).
Thanks!
Is there a way I can include just the so file in a library project for them?
Package an AAR containing the libraries, and host the AAR as an artifact for your customers. See my CWAC-AndDown library for an example. The AAR will contain your .so files for whatever architectures that you are supporting, plus a JAR of the compiled Java code that provides your Java API to the native code.
I also want them to be able to treat this library as they would any other (ie make cleans don't wreck it).
Well, by definition, make clean requires source. It also requires a makefile, which presumably you will not distributing, since that's useless without the source.
I have a library that I'm using in an Java application - it's important for certain functionality, but it's optional. Meaning that if the JAR file is not there, the program continues on without issue. I'd like to open source my program, but I can not include this library, which is necessary to compile the source code as I have numerous import statements to use the API. I don't want to maintain two code sets. What is the best way to remove the physical jar file from open source release, but still maintain the code to support it where other people could still compile it?
the typical approach taken is to define the wrapper API (i.e. interfaces) and include those interfaces in the open sourced code, and then provide configuration options where one can specify class names of classes that implement certain interfaces.
You will import API interfaces instead of importing classes directly into your open sourced code. This way, you are open sourcing the API but not the implementation of the parts that you do not want to open source or you cannot open source.
There are many examples, but take a look at JDBC API (interfaces) and JDBC drivers (implementation classes) for starters.
I was pretty much typing the same thing as smallworld with one addition. If this API were necessary you can use a project build tool like Maven to handle the dependencies on you project. If someone checks it out from source control with the pom they can download the dependencies for themselves and you don't have to include them in a source repo.
There's probably a number of ways to fix this, here's a couple I can think of:
If you have only a couple of methods you need to invoke in the 3rd party library, you could use reflection to invoke those methods. It creates really verbose code, that is hard to read though.
If you don't have too much of the API in the 3rd party library you use, you could also create a separate JAR file, containing just a non-functional shell of the classes in the library (just types with the same names and methods with the same signatures). You can then use this JAR to distribute and compile against. At run-time you'd replace it with the real JAR if available.
The most common way is probably to just create a wrapper API in a separate module/project for the code that is dependent on the 3rd party library, and possibly distribute a pre-built JAR. This might go against your wish to not maintain two code sets, but may prove to be the best and less painful solution in the long run.
I am working on a desktop application, I use Hibernate and HSQLDB. When I make my application a runnable jar file, it has a bigger fize size than I think. I see that the biggest part is from Hibernate and its dependencies. I am not sure if I need all of the Hibernate features. Is there a way to get rid of the parts of Hibernate and its dependency libraries which I don't use?
Under the /lib/ folder in Hibernate zip you will see a folder called /required/. For very basic Hibernate apps thats all you will need though you may need additional JARs for things such as JPA. I would start by only including the JARs in the lib/required/ directory, see if your project works, and if it doesn't add what you need to get your project working again.
perhaps you could use a tool to analyse your classes and dependencies (for e.g. http://www.dependency-analyzer.org/). Here is another post about it: How do I find out what jar files are actually used when compiling a java project.
the other way is to remove some jars (or even single class files) and try whether your application is still working or not. but i think this is not a very good way...
I can't think of a better tool for this than ProGuard.
ProGuard is a free Java class file shrinker, optimizer, obfuscator, and preverifier. It detects and removes unused classes, fields, methods, and attributes. It optimizes bytecode and removes unused instructions. It renames the remaining classes, fields, and methods using short meaningless names. Finally, it preverifies the processed code for Java 6 or for Java Micro Edition.