This question arise while trying to write test cases. Foo is a class within the framework library which I dont have source access to.
public class Foo{
public final Object getX(){
...
}
}
my applications will
public class Bar extends Foo{
public int process(){
Object value = getX();
...
}
}
The unit test case is unable to initalize as I can't create a Foo object due to other dependencies. The BarTest throws a null pointer as value is null.
public class BarTest extends TestCase{
public testProcess(){
Bar bar = new Bar();
int result = bar.process();
...
}
}
Is there a way i can use reflection api to set the getX() to non-final? or how should I go about testing?
As this was one of the top results for "override final method java" in google. I thought I would leave my solution. This class shows a simple solution using the example "Bagel" class and a free to use javassist library:
/**
* This class shows how you can override a final method of a super class using the Javassist's bytecode toolkit
* The library can be found here: http://jboss-javassist.github.io/javassist/
*
* The basic idea is that you get the super class and reset the modifiers so the modifiers of the method don't include final.
* Then you add in a new method to the sub class which overrides the now non final method of the super class.
*
* The only "catch" is you have to do the class manipulation before any calls to the class happen in your code. So put the
* manipulation as early in your code as you can otherwise you will get exceptions.
*/
package packagename;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.Modifier;
/**
* A simple class to show how to use the library
*/
public class TestCt {
/**
* The starting point for the application
*/
public static void main(String[] args) {
// in order for us to override the final method we must manipulate the class using the Javassist library.
// we need to do this FIRST because once we initialize the class it will no longer be editable.
try
{
// get the super class
CtClass bagel = ClassPool.getDefault().get("packagename.TestCt$Bagel");
// get the method you want to override
CtMethod originalMethod = bagel.getDeclaredMethod("getDescription");
// set the modifier. This will remove the 'final' modifier from the method.
// If for whatever reason you needed more than one modifier just add them together
originalMethod.setModifiers(Modifier.PUBLIC);
// save the changes to the super class
bagel.toClass();
// get the subclass
CtClass bagelsolver = ClassPool.getDefault().get("packagename.TestCt$BagelWithOptions");
// create the method that will override the super class's method and include the options in the output
CtMethod overrideMethod = CtNewMethod.make("public String getDescription() { return super.getDescription() + \" with \" + getOptions(); }", bagelsolver);
// add the new method to the sub class
bagelsolver.addMethod(overrideMethod);
// save the changes to the sub class
bagelsolver.toClass();
}
catch (Exception e)
{
e.printStackTrace();
}
// now that we have edited the classes with the new methods, we can create an instance and see if it worked
// create a new instance of BagelWithOptions
BagelWithOptions myBagel = new BagelWithOptions();
// give it some options
myBagel.setOptions("cheese, bacon and eggs");
// print the description of the bagel to the console.
// This should now use our new code when calling getDescription() which will include the options in the output.
System.out.println("My bagel is: " + myBagel.getDescription());
// The output should be:
// **My bagel is: a plain bagel with cheese, bacon and eggs**
}
/**
* A plain bagel class which has a final method which we want to override
*/
public static class Bagel {
/**
* return a description for this bagel
*/
public final String getDescription() {
return "a plain bagel";
}
}
/**
* A sub class of bagel which adds some extra options for the bagel.
*/
public static class BagelWithOptions extends Bagel {
/**
* A string that will contain any extra options for the bagel
*/
String options;
/**
* Initiate the bagel with no extra options
*/
public BagelWithOptions() {
options = "nothing else";
}
/**
* Set the options for the bagel
* #param options - a string with the new options for this bagel
*/
public void setOptions(String options) {
this.options = options;
}
/**
* return the current options for this bagel
*/
public String getOptions() {
return options;
}
}
}
you could create another method which you could override in your test:
public class Bar extends Foo {
protected Object doGetX() {
return getX();
}
public int process(){
Object value = doGetX();
...
}
}
then, you could override doGetX in BarTest.
Seb is correct, and just to ensure that you get an answer to your question, short of doing something in native code (and I am pretty sure that would not work) or modifying the bytecode of the class at runtime, and creating the class that overrides the method at runtime, I cannot see a way to alter the "finalness" of a method. Reflection will not help you here.
If your unit test case can't create Foo due to other dependencies, that might be a sign that you're not making your unit test right in the first place.
Unit tests are meant to test under the same circumstances a production code would run, so I'd suggest recreating the same production environment inside your tests. Otherwise, your tests wouldn't be complete.
If the variable returned by getX() is not final you can use the technique explained in What’s the best way of unit testing private methods? for changing the value of the private variable through Reflection.
public class Bar extends Foo{
public int process(){
Object value = getX();
return process2(value);
}
public int process2(Object value){
...
}
}
public class BarTest extends TestCase{
public testProcess(){
Bar bar = new Bar();
Mockobj mo = new Mockobj();
int result = bar.process2(mo);
...
}
}
what i did eventually was the above. it is a bit ugly... James solution is definitely much better than this...
Related
The Java reflection code in my Android application invokes a public static method in a package B, from a package A.
Recently, after some Gradle upgrades, I am unable to invoke the same method. My implementation fails with a NoSuchMethodFound exception. How can I get the implementation to be able to find this method?
I've tried printing all the available methods from the class. The result is all public non-static methods. No static methods are available to be invoked. The method I want to invoke is a static "getInstance" method which initializes the class and returns a singleton instance.
Calling Code:
implementationClass = Class.forName(CLIENT_CLASS_NAME, false, ClientProvider.class.getClassLoader());
final Method method = implementationClass.getMethod("getInstance", (Class[]) null);
result = method.invoke(null, (Object[]) null);
Called Code:
/**
* Public static method to be reflected.
*/
public static ClientImpl getInstance() {
return ClientImplHolder.INSTANCE;
}
/**
* Private class used to hold the lazily initialized singleton instance.
*/
private static class ClientImplHolder {
private static final ClientImpl INSTANCE = new ClientImpl();
}
When attempting to 'getMethod', I receive a NoSuchMethodException.
Not sure what I am doing wrong here, appreciate any help. Thanks!
Turns out Proguard was removing the method from the build since it was not being used elsewhere. Added an exception for the class and the issue went away.
If i understood correctly, you used reflection API wrong
just try this.
public class Test {
public static void main(String[] args) {
try {
ClientImpl client = (ClientImpl) Class.forName(ClientImpl.class.getCanonicalName())
.getMethod("getInstance")
.invoke(null);
System.out.println(client.toString() + " with some -> " + client.getSome());
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* Public static method to be reflected.
*/
class ClientImpl {
private final int some;
public int getSome() {
return some;
}
private ClientImpl(int some) {
this.some = some;
}
public static ClientImpl getInstance() {
return ClientImplHolder.INSTANCE;
}
/**
* Private class used to hold the lazily initialized singleton instance.
*/
private static class ClientImplHolder {
private static final ClientImpl INSTANCE = new ClientImpl(123);
}
}
and it will put correctly result
ClientImpl#<hashcode> with some -> 123
When you use static methods in reflection API, you don't need to call it ClassLoader explicitly, you have to put it's canonicalName in argument, then you can call it's methods.
Try to replace it,maybe it's a parameter problem.
final Method method = implementationClass.getMethod("getInstance");
result = method.invoke(null);
Starting in Android 9 (API level 28), the platform restricts which non-SDK interfaces your app can use. These restrictions apply whenever an app references a non-SDK interface or attempts to obtain its handle using reflection.
I am writing a JUnit test for code submitted to a competition. The rules of the competition require that certain methods not be called from other methods. (I unfortunately can not change the rules.)
The contestants are all implementing an interface we supplied which includes an add(K key, V value) method and a delete(K key) method. We need to test that entries do not implement delete by adding every other element to a new object and return that object.
We are also trying to avoid adding dependencies outside of the Java core since we are using a lot of automated tools (like the Marmoset Project) to test the hundreds of submissions.
I read through the documentation for Java Reflection and Instrumentation and nothing jumped out at me.
We are using Java 8 if it makes a difference.
AspectJ compile time weaving will probably be your best bet.
You will need to recompile the code with aspectj compiler and add advice to intercept the call.
If you give me more details I can show some example code.
You probably want a mocking library, and to use a "spy" test object. Using Mockito it might look something like this.
eg.
import static org.mockito.Mockito.*;
public class Test {
#Spy
ClassUnderTest classUnderTest;
#Before
public void init() {
MockitoAnnotations.initMocks(this);
}
#Test
public void deleteNeverCalled() {
// given
String key = randomString();
String value = randomString();
// when
classUnderTest.add(key, value)
// then
verify(classUnderTest, never()).delete(any());
}
}
This was my solution in the end. It looks like in the original question, I did not mention that this was a binary tree, so the compareTo function would be used constantly.
I created an Exception we could throw in our test framework and then detect.
public static class NotAllowedException extends RuntimeException
I created a new type that would have a flag that could be set to true by the testing framework before calling delete.
/**
* This class uses reflection to check whether {#link compareTo()} is being
* called inside the add method after the test decides it is done with the
* add method.
* It will throw a {#link NotAllowedException}.
*
* #author yakatz <email#domain.com>
*/
private class MyIntWrapper {
private boolean doneAdding = false;
public void doneAdding() {
this.doneAdding(true);
}
public void doneAdding(boolean b) {
this.doneAdding = b;
}
private class MyInteger implements Comparable<MyInteger> {
private Integer value;
public MyInteger(int value) {
this.value = value;
}
#Override
public int compareTo(MyInteger o) {
if (MyIntWrapper.this.doneAdding) {
StackTraceElement[] causes = Thread.currentThread().getStackTrace();
for (StackTraceElement cause : causes) {
if (cause.getClassName().equals("tree.Node") && cause.getMethodName().equals("add")) {
throw new NotAllowedException();
}
}
}
return this.value.compareTo(o.value);
}
}
}
I can then use the class in tests like this:
MyIntWrapper mir = new MyIntWrapper();
Tree<MyIntWrapper.MyInteger, String> tree = new Tree();
// Add stuff to the tree
mir.doneAdding();
MyIntWrapper.MyInteger mi = mir.new MyInteger(1);
tree = tree.delete(mi); // Will throw NotAllowedException if add() is called
Re-edited...
I'd like to use a superclass constructor which is hidden by the "#hide" Android tag (or whatever it is).
I'm about to extend a class which has been already extended twice (within the Android OS). I'd like to create my own subclass (i.e. outside the Android OS). Example subclass, taken from Android sources:
public class WifiP2pDnsSdServiceInfo extends WifiP2pServiceInfo {
...
private WifiP2pDnsSdServiceInfo(List<String> queryList) {
super(queryList); // <-- this is what I'm trying to do, too
}
public static WifiP2pDnsSdServiceInfo newInstance(String instanceName,
String serviceType, Map<String, String> txtMap) {
...
ArrayList<String> queries = new ArrayList<String>();
...
return new WifiP2pDnsSdServiceInfo(queries);
}
}
The superclass looks like this:
public class WifiP2pServiceInfo implements Parcelable {
...
// this is marked as #hidden therefore inaccessible!
protected WifiP2pServiceInfo(List<String> queryList) {
if (queryList == null) {
throw new IllegalArgumentException("query list cannot be null");
}
mQueryList = queryList;
}
}
And all I want to do is to make another kind of WifiP2pServiceInfo, similar to the WifiP2pDnsSdServiceInfo example above. I can't just inherit & call super() because the superclass constructor is tagged by Android's "#hide", therefore unusable without reflection for non-system programmers.
So my question is how to access / call the superclass constructor if I can't do it by a plain super() call? Reflection should come handy here but I'm not very experienced in Java programming.
After some research I'm able to answer the question by myself.
Short answer: I can't do this because if the superclass constructor is protected and hidden, the compiler is going to complain even if I found a way how to call the constructor via reflection.
Long answer: it turns out it's not so complicated to "unhide" this stuff. Following this tutorial I'm able to extend the class to my needs.
See? A lot of noise for nothing, this is the answer I was looking for.
You want to find that constructor and set its availability to true.
But this is a dangerous operation that you should not attempt lightly. It's a dirty secret that private need not mean private, but I would still expect you to honor the wishes of the class designer and not circumvent.
Besides, you don't need to. If I understand your requirement, I've posted an example that will do what you want.
This works, because of this:
The protected modifier specifies that the member can only be accessed
within its own package (as with package-private) and, in addition, by
a subclass of its class in another package.
I think you've confused the meaning of the protected modifier.
Parent w/ protected ctor:
package foo;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* Parent with protected constructor
* User: MDUFFY
* Date: 3/27/14
* Time: 5:18 PM
* #link http://stackoverflow.com/questions/22698501/reflection-how-to-call-superclass-constructor-which-is-hidden/22698543?noredirect=1#comment34586243_22698543
*/
public class Foo {
private List<String> x;
protected Foo(List<String> y) {
this.x = ((y == null) ? new ArrayList<String>() : new ArrayList<String>(y));
}
public List<String> getX() {
return Collections.unmodifiableList(this.x);
}
#Override
public String toString() {
return "Foo{" +
"x=" + x +
'}';
}
}
Child extends Parent:
package bar;
import foo.Foo;
import java.util.Arrays;
import java.util.List;
/**
* Child of parent with protected ctor
* User: MDUFFY
* Date: 3/27/14
* Time: 5:22 PM
* #link http://stackoverflow.com/questions/22698501/reflection-how-to-call-superclass-constructor-which-is-hidden/22698543?noredirect=1#comment34586243_22698543
*/
public class Bar extends Foo {
public static void main(String[] args) {
Bar bar = new Bar(Arrays.asList(args));
System.out.println(bar);
}
public Bar(List<String> y) {
super(y);
}
}
This will compile and run.
I am very new in Reflection and I have a doubt like:
public void setAccessible(boolean flag) throws SecurityException
This method has a boolen parameter flag, which indicates the new accessibility of any fields or methods.
For an example if we are try to access a private method of a class from outside the class then we fetch the method using getDeclaredMethod and set the accessibility as true, so it can be invoked, like: method.setAccessible(true);
Now in which scenario we should use method.setAccessible(false); , for an example it can be used when there is a public method and we set the accessibility as false. But what is the need of that? Is my understanding clear?
If there is no use of method.setAccessible(false) then we can change the method signature like:
public void setAccessible() throws SecurityException
Probably you would never do setAccessible(false) in your entire life. This is because setAccessible doesn't the change the visiblity of the a member permanently. When you to something like method.setAccessible(true) you are allowed to make subsequent calls on this method instance even if the method in the original source is private.
For example consider this:
A.java
*******
public class A
{
private void fun(){
....
}
}
B.java
***********
public class B{
public void someMeth(){
Class clz = A.class;
String funMethod = "fun";
Method method = clz.getDeclaredMethod(funMethod);
method.setAccessible(true);
method.invoke(); //You can do this, perfectly legal;
/** but you cannot do this(below), because fun method's visibilty has been
turned on public only for the method instance obtained above **/
new A().fun(); //wrong, compilation error
/**now you may want to re-switch the visibility to of fun() on method
instance to private so you can use the below line**/
method.setAccessible(false);
/** but doing so doesn't make much effect **/
}
}
Scenario: you removed protection from a private field with Field.setAccessible(true), read it and returned the field into original state with Field.setAccessible(false).
//create class PrivateVarTest { private abc =5; and private getA() {sop()}}
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class PrivateVariableAcc {
public static void main(String[] args) throws Exception {
PrivateVarTest myClass = new PrivateVarTest();
Field field1 = myClass.getClass().getDeclaredField("a");
field1.setAccessible(true);
System.out.println("This is access the private field-"
+ field1.get(myClass));
Method mm = myClass.getClass().getDeclaredMethod("getA");
mm.setAccessible(true);
System.out.println("This is calling the private method-"
+ mm.invoke(myClass, null));
}
}
object ScalaTrueRing {
def rule = println("To rule them all")
}
this piece of code will be compiled into java byte code, if I decompile it, then the equivalent Java code is similar to this:
public final class JavaTrueRing
{
public static final void rule()
{
ScalaTrueRing..MODULE$.rule();
}
}
/* */ public final class JavaTrueRing$
/* */ implements ScalaObject
/* */ {
/* */ public static final MODULE$;
/* */
/* */ static
/* */ {
/* */ new ();
/* */ }
/* */
/* */ public void rule()
/* */ {
/* 11 */ Predef..MODULE$.println("To rule them all");
/* */ }
/* */
/* */ private JavaTrueRing$()
/* */ {
/* 10 */ MODULE$ = this;
/* */ }
/* */ }
it's compiled into two classes, and if I use Scala.net compiler, it'll be compiled into MSIL code, and the equivalent C# code is like this:
public sealed class ScalaTrueRing
{
public static void rule()
{
ScalaTrueRing$.MODULE$.rule();
}
}
[Symtab]
public sealed class ScalaTrueRing$ : ScalaObject
{
public static ScalaTrueRing$ MODULE$;
public override void rule()
{
Predef$.MODULE$.println("To rule them all");
}
private ScalaTrueRing$()
{
ScalaTrueRing$.MODULE$ = this;
}
static ScalaTrueRing$()
{
new ScalaTrueRing$();
}
}
It's also compiled into two classes.
Why do Scala compilers(the one for Java and the one for .NET) do this?
Why does not it just call the println method in the static rule method?
It is important to understand that in scala, an object actually is a first class citizen: it is an actual instance that can be passed around as any other object.
By example:
trait Greetings {
def hello() { println("hello") }
def bye() { println("bye") }
}
object FrenchGreetings extends Greetings {
override def hello() { println("bonjour") }
override def bye() { println("au revoir") }
}
def doSomething( greetings: Greetings ) {
greetings.hello()
println("... doing some work ...")
greetings.bye()
}
doSomething( FrenchGreetings )
Unlike with static methods, our singleton object has full polymorphic beheviour. doSomething will indeed call our overriden hello and bye methods, and not the default implementations:
bonjour
... doing some work ...
au revoir
So the object implementation must necessarily be a proper class. But for interoperability with java,
the compiler also generates static methods that just forward to the unique instance (MODULE$) of the class (see JavaTrueRing.rule()).
This way, a java program can access the methods of the singleton object as a normal static method.
Now you might ask why scala does not put the static method forwarders in the same class as the instance methods. This would give us something like:
public final class JavaTrueRing implements ScalaObject {
public static final MODULE$;
static {
new JavaTrueRing();
}
public void rule() {
Predef.MODULE$.println("To rule them all");
}
private JavaTrueRing() {
MODULE$ = this;
}
// Forwarders
public static final void rule() {
MODULE$.rule();
}
}
I believe that the main reason why this can't be as simple is because in the JVM you cannot have in the same class an instance method and a static method wth the same signature.
There might be other reasons though.
Paraphrasing from "Programming in Scala" - Because a scala companion object (singleton object) is more than just a holder of static methods. By being an instance of a different Java class, it allows the developer to extend singleton objects and mix-in traits. This cannot be done with static methods.
This Blog entry "A Look at How Scala Compiles to Java" should answer your question
Typically ClassName$.class are results of inner classes - Scala is obviously slightly different.