Interesting question here. So I have a .jar I received and it is obfuscated, meaning when I decompile the .class files it doesnt show up 100% perfect so I cannot recompile it. However the only method I need to change has been converted perfectly (but the class does not)). Is there a way to somehow change the .java code and inject replace the method within the class file without totally recompiling?
If this fails im going to bytecode.
Thanks!
EDIT: As a follow up question / or a hack around replacing the WHOLE method. I'm really just trying to change a variable that the method generates locally. If there are any better ways to do that.
Depending on what you really want to do, I do not recommand to decompile / modify / recompile the code (be it for legal, maintainance, understandability, testability reasons.)
Bytecode manipulation may not be the best solution either, but if you want to follow this way have a look at the ASM project, it's a widespread bytecode manipulation framework used by many known projects.
If I were you I would first give a try to aspects (AspectJ.) The power of aspects is that you don't touch existing code, but tell the VM what to do when / before / after / in place of calling a specific method. It allows you to point out the exact context and change, enhance the behavior of the code, by writing your own code in a decoupled fashion.
Hope it helps.
Sorry, this is not an answer, but it is too long for a comment...
I am reflecting this code, not using it as a library. So I dont really need to "use" this code (aka I'm just reflecting and calling functions at runtime).
I'd call the "reflecting and calling functions at runtime" as using the code.
There might be the reasons why to do that, but I'd prefer to simply call the function as a library function if possible (which should be possible if you can do the same using reflection).
...and manually overload it.
There is nothing simpler that extending the class and override a "wrong" method. As of my understanding even if you want to "inject" the method, you have to have the code somewhere. How you will test such code? It'd be a lot easier to just extend the class... Can you specify in bigger detail what you want to achieve with a reasoning why you cannot use what I wrote above?
If you want to change just one method you can actually extend the class and then #Override the method!
Don't know if this is the perfect way to do it,but it works!
Related
So I been messing around and created a library with my favorite methods that I use several projects. But those annoying unused method and method can be private (because it's intended to be used publicly but also used in the library somewhere else) warnings keep appearing and I want to keep the library clean.
Is there a way to tell the compiler that a class or file is intended to be used as a library?
Currently am using #Suppress("unused", "MemberVisibilityCanBePrivate") but this just feels wrong.
Those "annoying" unused method and method can be private warnings, actually are saying that you are neven calling those methods, and that's right when it comes to be an library, but it is wrong if we consider that all single public methdo must have a unit test for it. If you had a single junit testing such methods the compiler/checker would not bother you with that ;)
Solution: create junit for those library methods and will get ride of those messages and at same time you will get a safer code!
Whenever I program, I seem to accumulate a lot of "trash" code, code that is not in use anymore. Just to keep my code neat, and to avoid making any expensive and unnecessary computations, Is there an easy way to tell if there is code that is not being used?
One of the basic principles which will help you in this regard is to reduce visibility of everything as much as possible. If a class can be private don't make it default, protected or public. Same applies for methods and variables. It is much easier when you can say for sure if something is not being used outside a class. In cases like this even IDEs like Eclipse and IntelliJ Idea will suggest you about unused code.
Using this practice while developing and refactoring code is the best way to clean unused code confidently without the possibility of breaking the application. This will help in scenarios even when reflection is being used.
It's difficult to do in Java since it's a reflective language. (You can't simply hunt for calls to a certain class or function, for example, since reflection can be used to call a function using strings that can only be resolved at runtime.)
So in full generality, you cannot be certain.
If you have adequate unit tests for your code base then the possibility of redundant code should not be a cause for concern.
I think "unused code" means the code that is always not executed at runtime. I hope I interpreted you correctly.
The way to do a simple check on this is very easy. Just use IntelliJ IDEA to write your code. It will tell you that parts of your code that will never be executed and also the parts where the code can be simplified. For example,
if (x == 5) {
}
And then it will tell you that this if statement is redundant. Or if you have this:
return;
someMethod();
The IDE will tell you that someMethod() can never be reached. And it also provides a lot of other cool features.
But sometimes this isn't enough. What if you have
if (x == 5) {
someMethod();
}
But actually in your code, x can only be in the range of 1 to 4? The IDE won't tell you about this. You can use a tool that shows your code coverage by running lots of tests. Then you can see which part of your code is not executed.
If you don't want to use such a tool, you can put breakpoints in your methods. Then run some tests by hand. When the debugger steps through your code, you can see exactly where the code goes and exactly which piece(s) of code is not executed.
Another method to do this is to use the Find/Replace function of the IDE. Check if some of your public/private methods are not being called anywhere. For example, to check whether someMethod() is called, search for someMethod in the whole project and see if there are occurrences other than the declaration.
But the most effective way would be,
Stop writing this kind of code in the first place!
i think the best way to check that is to install a plugin of coverage like eclemma and create unit and integration tests to get 100% of coverage of the code that accomplish the use code/task you have.
The code that don't need to be tested or don't pass over it after the tests are completed and run, is code that you are not using
Try to avoid accumulating trash in the first place. Remove stuff you don't need anymore. (You could make a backup or better use a source code management system.)
You should also write unit tests for your functions. So you know if it still works after you remove something.
Aside from that, most IDEs will show you unused local variables and private methods.
I do imagine situation when you have app developed by years and some part of your functions doesn't used anymore even they still working. Example: Let's assume you make some changes on internal systems when specific event occured but it is not occurs anymore.
I would say you could use AspectJ to obtain such data / log and then analyze after some time.
I'm aware you cannot actually Swizzle in Java.
I was doing some research and I think 'maybe' you can do Reflection in Java to accomplish Swizzle like behaviour (that you can do on iOS).
The culprit (and one of the worst design decisions I've ever seen) is the addView() function on all Android ViewGroup objects. You must explicitly check if the parent is null (you sometimes even need to cast the parent to get the behaviour you need!). Gross.
I want to change the behaviour of this (without creating a million subclasses) by having the addView() method do this check automatically so the client code can ignore this.
Is this something I can do with Reflection (from what I grasp it would require special runtime calling, instead of actually changing the root method call [so maybe not good enough]), or something else? Or am I barking up the wrong tree?
As you mentioned, without creating a million subclasses (or better put, one subclass for every class where you would like to override the addView implementation) this doesn't seem possible. This would actually be the right way to do it, and it also means that you can use these subclasses in XML layout files.
Reflection would allow you to inspect classes/interfaces/fields/methods at runtime, but it won't allow you to change their already defined behaviour provided by the underlying implementation which has been compiled. Although some changes are possible, such as making private methods/fields accessible.
Grey-area options incoming...
One direction worth looking into would be Mockito, which allows you to create spies around existing object instances that would allow you to override the default implementation. This is achieved through Java's proxies and InvocationHandlers. However, at this point I'll stop and say that your production code should not contain any test code and Mockito is clearly meant for that. More so considering that, at least in the past, it used to be hard (if not impossible) to put proxies around some of Android's classes such as Views and Contexts. I believe this has been resolved by DexMaker, which I have less knowledge of myself but it does allow you to perform runtime code generation. This would be another direction worth looking at. I personally think that neither of these should be taken as possible solutions worthy of production code, but something to have a play with for your own curiosity and to learn from.
I have a class which behavior I would like to change. I need to replace private method with another realization. Common reflection techniques allow to modify private variable or to invoke private methods. But I find little information about replacing entire methods.
I presume that there are advanced techniques to do so. May be its impossible with standard java reflection but there are probably other tools to recompile byte code in runtime.
Modify & replace:
One option is to mask the class with a modified copy (modify code, recompile code, add modified classes to the classpath before patched classes), similar to the approach used here to inspect how a normally unavailable method works.
If you do not have sources to modify, you can "reverse" almost any .class file into more-or-less readable source code using decompilers. Notice that, depending on licensing, you may not have permission to do so and/or to redistribute your changes.
Patch via agent:
You can also patch the methods using the -javaagent:<jarpath>[=<options>] commant-line option. The "agent" is a jar that gets to modify loaded classes and alter their behaviour. More information here.
Mock:
If you have control over where the methods are called, you can replace the target instance with a stubbed version. Libraries such as Mockito make this very, very easy:
LinkedList mockedList = mock(LinkedList.class);
// stubbing appears before the actual execution
when(mockedList.get(0)).thenReturn("first");
Even though Mockito does not support mocking private methods natively (mostly because it is considered bad manners to look at other classes' privates), using PowerMock allows you to do so (thanks, #talex).
You can't replace method in runtime (at least without hack into JVM). But you can replace whole class. There are several way to do it. For example you can use thing called "aspect".
But from my experience I can say that if you need to do this you have wrong turn somewhere in beginning of you way.
Maybe you better make one step back and look at whole picture
Instead of going for advanced techniques, there is a simple trick to achieve this.
If you class is part of an open-source jar, get source code of this class file from grepcode.com. Change the method that you want to change and compile it. And update your jar file/classpath with this updated class file.
Is there any diff tool specifically for Java that doesn't just highlight differences in a file, but is more complex?
By more complex I mean it'd take 2 input files, the same class file of different versions, and tell me things like:
Field names changed
New methods added
Deleted methods
Methods whose signatures have changed
Methods whose implementations have changed (not interested in any more detail than that)
Done some Googling and can't find anything like this...I figure it could be useful in determining whether or not changes to dependencies would require a rebuild of a particular module.
Thanks in advance
Edit:
I suppose I should clarify:
I'm not bothered about a GUI for the tool, it'd be something I'm interested in calling programmatically.
And as for my reasoning:
To workout if I need to rebuild certain modules/components if their dependencies have changed (which could save us around 1 hour per component)... More detailed explanation but I don't really see it as important.
To be used to analyse changes made to certain components that we are trying to lock down and rely on as being more stable, we are attempting to ensure that only very rarely should method signatures change in a particular component.
You said above that Clirr is what you're looking for.
But for others with slightly differet needs, I'd like to recommend JDiff. Both have pros and cons, but for my needs I ended up using JDiff. I don't think it'll satisfy your last bullet point and it's difficult to call programmatically. What it does do is generate a useful report for API differences.