Why a public static method is not accessible? - java

I'm trying to reflect the parse(CharSequence, DateTimeFormatter) methods from classes which each extends the TemporalAccessor class.
private static final Map<Class<?>, MethodHandle> PARSE_HANDLES = synchronizedMap(new HashMap<>());
static <T extends TemporalAccessor> MethodHandle parseMethodHandle(final Class<T> clazz) {
if (clazz == null) {
throw new NullPointerException("clazz is null");
}
return PARSE_HANDLES.computeIfAbsent(clazz, k -> {
try {
final Method method = clazz.getMethod("parse", CharSequence.class, DateTimeFormatter.class);
log.debug("method: {}, {}", method, method.isAccessible());
// i don't understand; public static method is not accessible? yet it isn't.
assert method.isAccessible(); // NOT GOOD with UTs
return MethodHandles.lookup().unreflect(method);
} catch (final ReflectiveOperationException roe) {
throw new RuntimeException(roe);
}
});
}
With the YearMonth class, I got this.
method: public static java.time.YearMonth java.time.YearMonth.parse(java.lang.CharSequence,java.time.format.DateTimeFormatter), false
Why a public static method is not accessible?

See the documentation for isAccessible:
This method is deprecated because its name hints that it checks if the reflected object is accessible when it actually indicates if the checks for Java language access control are suppressed. This method may return false on a reflected object that is accessible to the caller. To test if this reflected object is accessible, it should use canAccess(Object).
(My emphasis.)

With the Java Reflection API, you can override the accessibility of methods by setting the accessible flag. This can be performed by method.setAccessible(true).
Now the isAccessible() method does not what you think it does, but it simply checks, if the standard java access checks are currently overridden.
This means, that you can of course invoke the method with reflection if the standard access modifiers allow it. Otherwise, you had to set the accessible flag.

Related

How to check if a class has overriden a default method from an interface using Reflection in Kotlin or Java?

I have an interface with a default method, and two classes which implement this interface. One of the classes overrides the default method, and the other does not.
interface MyType {
fun giveHello(): String = "Hello!"
}
class Polite: MyType {
// Does not override giveHello()
}
class Rude: MyType {
override fun giveHello(): String = "I don't like you"
}
I get access to the giveHello method using reflection like this:
val methodOfPolite = Polite::class.java.getDeclaredMethod("giveHello")
val methodOfRude = Rude::class.java.getDeclaredMethod("giveHello")
There's one weird thing here. The polite class does not override the giveHello method, but the declaringClass of this method object still points to Polite.
So is there a way I can check whether the class actually did override the default interface method or not?
My use case looks something like this (assuming we can get the behaviour I'm asking for in a property called isOverriden):
if (methodOfPolite.isOverriden) {
// do something
} else {
// do something else
}
As described in KT-4779, currently Kotlin default functions are not implemented using actual Java/JVM default methods. The default implementation lives in a static method instead, and all classes using that default implementation just call that static method. This is done to ensure Kotlin default functions also work on the 1.6 JVM target which doesn't have them yet.
So your code roughly compiles to this Java equivalent:
public interface MyType {
public String giveHello();
public static class MyTypeImpls {
public static String giveHello() { return "Hello!" }
}
}
public final class Polite implements MyType {
//does not override
public String giveHello() { return MyType.MyTypeImpls.giveHello() }
}
public final class Rude implements MyType {
//does override
override fun giveHello() { return "I don't like you" }
}
This is why java reflection thinks both classes override the function, ie because they actually do.
You need to use Kotlin reflection here, notably declaredMemberFunctions and memberFunctions:
fun overridesGiveHello<T: MyType>(cls: KClass<T>) =
cls.memberFunctions.first { it.name == "giveHello" } in cls.declaredFunctions
println(overridesGiveHello(Polite::class)) //false
println(overridesGiveHello(Rude::class)) //true
In this specific case I think the isDefault() method should return true.
I would have expected Polite::class.java.getMethod("giveHello") to return the method, but not getDeclaredMethod(), but we are in the world of using Java reflection on Kotlin classes and interfaces. The Java expectations may not be met.
You could use kotlin reflection though, use declaredMembers to get the properties and functions from the KClass. Note, import from kotlin.reflect.full is required, since extension methods are used.

In Java, how do we protect access of lazy fields?

If a Java class has a field that is initialized lazily or on demand, how can we ensure that access to the lazy field is via it's initializing access method?
By way of context, we recently had a situation in which a developer added access to an object that was initialized lazily, but not via its initializing access method. This wasn't caught at compilation or in unit tests, but then caused runtime errors.
For example - in the following SSCCE, _lazyObject is initialized via the getLazyObject() method. However, if there are other methods (in the class, because it already has a private access modifier) that would want to use _lazyObject, we should access via the getLazyObject() method, as otherwise it may not have been initialized.
public class MyObject {
private transient volatile Object _lazyObject;
public Object getLazyObject() {
if (_lazyObject == null) {
synchronized (this) {
if (_lazyObject == null) {
_lazyObject = new Object();
}
}
}
return _lazyObject;
}
public void doSomething() {
Object a = _lazyObject; // may be null - will compile, but may cause runtime errors!
Object b = getLazyObject(); // subject to exceptions, will not be null - this is how it should be accessed.
// do something...
}
}
How can we ensure that the access of _lazyObject is via getLazyObject()?
Is this possible in the code within MyObject?
Alternatively, is it possible to ensure this via unit tests?
Ok, so I'm open to further suggestions, but this is the best solution that I have come up with so far.
We can 'protect' the lazy variable in an initializing object - I thought about writing this myself, but found that there are good implementations of this in Apache Commons Lang (LazyInitializer) and Google Guava (Supplier). (Credit to Kenston Choi's answer to this question.)
For example - to clarify, I've changed the lazy object class from Object to a placeholder T:
public class MyObject {
private transient Supplier<T> _lazyObject = Suppliers.memoize(new Supplier<T>() {
#Override
public T get() {
return ...; // make T
}
});
public T getLazyObject() {
return _lazyObject.get();
}
public void doSomething() {
Supplier<T> a = _lazyObject; // a is actually the Supplier
// ... but we can access either via the method
T b = getLazyObject();
// or the Supplier:
T c = _lazyObject.get();
// do something...
}
}
However, as per the comments above - one of my main use cases is serializing/de-serializing objects containing lazy fields across JVMs. In this case, after de-serialization, the Supplier will be null. As such, we need to initialize the Supplier after deserialization.
For example, using the most simple approach:
public class MyObject {
private transient Supplier<T> _lazyObject = makeSupplier();
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
in.defaultReadObject();
_lazyObject = makeSupplier();
}
private Supplier<T> makeSupplier() {
return Suppliers.memoize(new Supplier<T>() {
#Override
public Tget() {
return ...; // make T
}
});
}
}

How to make a java proxy object to java.nio.ByteBuffer instance?

I have a public abstract class java.nio.ByteBuffer instance which is actually an instance of private class java.nio.HeapByteBuffer and I need to make a proxy object which would call some invocation method handler to check access permissions and then call the invoked method on the actual instance.
The problem is that the java.nio.ByteBuffer class has only private constructors and also has some final methods, thus I can not create proxy instances with javassist.util.proxy.ProxyFactory class.
So, how can I make a proxy object to control the invocation of a java.nio.ByteBuffer instance including those final methods invocation?
Please be aware that I am presenting a solution based on my own (FOSS) framework Byte Buddy which is however already mentioned as a potential solution in one of the comments.
Here is a simple proxy approach which creates a subclass. First, we introduce a type for creating proxies for ByteBuffers:
interface ByteBufferProxy {
ByteBuffer getOriginal();
void setOriginal(ByteBuffer byteBuffer);
}
Furthermore, we need to introduce an interceptor to use with a MethodDelegation:
class Interceptor {
#RuntimeType
public static Object intercept(#Origin(cacheMethod = true) Method method,
#This ByteBufferProxy proxy,
#AllArguments Object[] arguments)
throws Exception {
// Do stuff here such as:
System.out.println("Calling " + method + " on " + proxy.getOriginal());
return method.invoke(proxy.getOriginal(), arguments);
}
}
This interceptor is capable of intercepting any method as the #RuntimeType casts the return type in case that it does not fit the Object signature. As you are merely delegating, you are safe. Plase read the documentation for details. As you can see from the annotations, this interceptor is only applicable for instances of ByteBufferProxy. Bases on this assumption, we want to:
Create a subclass of ByteBuffer.
Add a field to store the original (proxied) instance.
Implement ByteBufferProxy and implement the interface methods to access the field for the stored instance.
Override all other methods to call the interceptor that we defined above.
This we can do as follows:
#Test
public void testProxyExample() throws Exception {
// Create proxy type.
Class<? extends ByteBuffer> proxyType = new ByteBuddy()
.subclass(ByteBuffer.class)
.method(any()).intercept(MethodDelegation.to(Interceptor.class))
.defineField("original", ByteBuffer.class, Visibility.PRIVATE)
.implement(ByteBufferProxy.class).intercept(FieldAccessor.ofBeanProperty())
.make()
.load(getClass().getClassLoader(), ClassLoadingStrategy.Default.WRAPPER)
.getLoaded();
// Create fake constructor, works only on HotSpot. (Use Objenesis!)
Constructor<? extends ByteBufferProxy> constructor = ReflectionFactory
.getReflectionFactory()
.newConstructorForSerialization(proxyType,
Object.class.getDeclaredConstructor());
// Create a random instance which we want to proxy.
ByteBuffer byteBuffer = ByteBuffer.allocate(42);
// Create a proxy and set its proxied instance.
ByteBufferProxy proxy = constructor.newInstance();
proxy.setOriginal(byteBuffer);
// Example: demonstrates interception.
((ByteBuffer) proxy).get();
}
final methods are obviously not intercepted. However as the final methods in ByteBuffer only serve as convenience methods (e.g. put(byte[]) calls put(byte[],int,int) with the additional arguments 0 and the array length), you are still able to intercept any method invocation eventually as these "most general" methods are still overridable. You could even trace the original invocation via Thread.currentCallStack().
Byte Buddy normally copies all constructors of its super class if you do not specify another ConstructorStrategy. With no accessible constructor, it simply creates a class without constructors what is perfectly legal in the Java class file format. You cannot define a constructor because, by definition, this constructor would need to call another constructor what is impossible. If you defined a constructor without this property, you would get a VerifierError as long as you do not disable the verifier altogether (what is a terrible solution as it makes Java intrinsically unsafe to run).
Instead, for instantiation, we call a popular trick that is used by many mocking frameworks but which requires an internal call into the JVM. Note that you should probably use a library such as Objenesis instead of directly using the ReflectionFactory because Objenesis is more robust when code is run on a different JVM than HotSpot. Also, rather use this in non-prduction code. Do however not worry about performance. When using a reflective Method that can be cached by Byte Buddy for you (via cacheMethod = true), the just-in-time compiler takes care of the rest and there is basically no performance overhead (see the benchmark on bytebuddy.net for details.) While reflective lookup is expensive, reflective invocation is not.
I just released Byte Buddy version 0.3 and I am currently working on documentation. In Byte Buddy 0.4, I plan to introduce an agent builder which allows you to redefine classes during load-time without knowing a thing about agents or byte code.
I can suggest you 2 solutions.
First, simple, not universal, but probably useful for you.
As far as I can see ByteBuffer has several package-private constructors that allow its subclassing and the following final methods:
public final ByteBuffer put(byte[] src) {
public final boolean hasArray() {
public final byte[] array() {
public final int arrayOffset() {
public final ByteOrder order() {
ByteBuffer extends Buffer that declares some of these methods:
public final boolean hasArray() {
public final Object array() {
public final int arrayOffset() {
As you can see, put() and order() are absent here, return type of array() is a little bit confusing, but still can be used.
So, if you use only these 3 methods you can subclass Buffer and create universal wrapper that wraps any other Buffer including ByteBuffers. If you want you can use javaassist's proxy although IMHO it is not necessarily here.
Second, more universal but more tricky solution. You can create agent that removes final modifiers from speicific class (ByteBuffer in your case) during class loading. Then you can create javassist proxy.
Variation of second solution is following. Copy ByteBuffer soruce code to separate project. Remove final modifiers and compile it. Then push it into bootstrap classpath. This solutions is probably easier than second.
Good luck anyway.
Thanks to #raphw I have managed to make a proxy object construction class which makes a proxy for java.nio.ByteBuffer but that class has final methods which I can not overcome and they are extensively used in the required code, those final methods are Buffer.remaining() and Buffer.hasRemaining(), thus they just can not be proxy mapped.
But I would like to share the classes I have made, just as a report.
public final class CacheReusableCheckerUtils {
private static ByteBuddy buddy = new ByteBuddy();
private static Objenesis objenesis = new ObjenesisStd();
public static <T> T createChecker(T object) {
return createChecker(new CacheReusableCheckerInterceptor<>(object));
}
public static <T> T createChecker(CacheReusableCheckerInterceptor<T> interceptor) {
return objenesis.getInstantiatorOf(createCheckerClass(interceptor)).newInstance();
}
private static <T> Class<? extends T> createCheckerClass(CacheReusableCheckerInterceptor<T> interceptor) {
Class<T> objectClass = interceptor.getObjectClass();
Builder<? extends T> builder = buddy.subclass(objectClass);
builder = builder.implement(CacheReusableChecker.class).intercept(StubMethod.INSTANCE);
builder = builder.method(MethodMatchers.any()).intercept(MethodDelegation.to(interceptor));
return builder.make().load(getClassLoader(objectClass, interceptor), Default.WRAPPER).getLoaded();
}
private static <T> ClassLoader getClassLoader(Class<T> objectClass, CacheReusableCheckerInterceptor<T> interceptor) {
ClassLoader classLoader = objectClass.getClassLoader();
if (classLoader == null) {
return interceptor.getClass().getClassLoader();
} else {
return classLoader;
}
}
}
public class CacheReusableCheckerInterceptor<T> {
private T object;
private boolean allowAccess;
private Throwable denyThrowable;
public CacheReusableCheckerInterceptor(#NotNull T object) {
this.object = object;
}
#SuppressWarnings("unchecked")
public Class<T> getObjectClass() {
return (Class<T>) object.getClass();
}
#RuntimeType
public final Object intercept(#Origin(cacheMethod = true) Method method, #This T proxy, #AllArguments Object[] arguments) {
try {
switch (method.getName()) {
case "allowAccess":
allowAccess();
return null;
case "denyAccess":
denyAccess();
return null;
default:
return invokeMethod(method, arguments);
}
} catch (Exception e) {
throw new CacheReusableCheckerException(method, object, proxy, e);
}
}
private Object invokeMethod(Method method, Object[] arguments) throws IllegalAccessException, InvocationTargetException {
checkMethodAccess(method.getName());
return method.invoke(object, arguments);
}
private void allowAccess() {
if (allowAccess) {
error("double use");
}
allowAccess = true;
onAccessAllowedAfter(object);
}
private void denyAccess() {
if (!allowAccess) {
error("double free");
}
onAccessDeniedBefore(object);
allowAccess = false;
denyThrowable = new Throwable();
}
private void checkMethodAccess(String name) {
if (!allowAccess) {
switch (name) {
case "hash":
case "equals":
case "toString":
case "finalize":
break;
default:
error("use after free");
}
}
}
private void error(String message) {
throw new CacheReusableCheckerException(message, denyThrowable);
}
protected void onAccessAllowedAfter(T object) {
}
protected void onAccessDeniedBefore(T object) {
}
}
public interface CacheReusableChecker {
void allowAccess();
void denyAccess();
}

Java Map of References to Singletons

I'd like to create a map of singleton classes that I can access via a cross reference in order to respond to a specific request. I have the following implemented, but having trouble getting to an actual reference that I can call getInstance() on.
Map<Integer, Class<? extends Thing>> xref = new HashMap<Integer, Class<? extends Thing>>();
xref.put(1, ThingOne.class);
xref.put(2, ThingTwo.class);
Class<? extends Thing> t = xref.get(1);
Ultimately then do something like...
something.perform(arg1, arg2);
Can't figure out how to get from "t" to "something", or if that's possible given the way I have it coded. I tried calling .cast(Thing.class).getInstance(), but got a Cast exception. Also tried reflection to get the getInstance() method, but no luck there either.
It may be I'm going down the wrong path altogether. Given 1..n possible functions, any given instance of the solution may only require a subset of these. In addition, I'd like to easily add/delete classes and manage the interface through config vs. a bunch of object instantiations at startup time.
Thanks!!!
I don't quite understand your purpose in creating this map. From what you've written, it seems you could simply put static getInstance() methods, that return singletons, on each relevant class. Or even more trivial: put each shared instance as a static final field of its class.
If you must use a map, don't use an integer as a key. The class is the key, and its instance is the value. Something like:
private static final Map<Class<?>,Object> singletons = new HashMap<>();
public static synchronized <T> T getSingleton(Class<T> klass) {
Object obj = singletons.get(klass);
if (obj == null) {
try {
obj = klass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
}
singletons.put(klass, obj);
}
return klass.cast(obj);
}
The creation code there is icky and requires a public no-arg constructor. You could alternatively call via reflection a static, specifically named method on each class to create the desired instance ("createInstance"), which might be a bit more flexible, but when you do that, it once again asks why bother with the map, when you could call a method on the class directly?
One interesting possibility with the map is to supply functions to create instances. In Java 8 syntax (import java.util.function.Supplier):
private static final Map<Class<?>,Object> singletons = new HashMap<>();
public static synchronized <T> T getSingleton(Class<T> klass) {
Object obj = singletons.get(klass);
if (obj instanceof Supplier) {
obj = ((Supplier<?>)obj).get();
singletons.put(klass, obj);
}
return klass.cast(obj);
}
public static synchronized <T> void declareSingleton(Class<T> klass, Supplier<T> supplier) {
if (Supplier.class.isAssignableFrom(klass)) {
// prevent Supplier<Supplier<?>> weirdness;
// could use separate maps if those are really needed
throw new UnsupportedOperationException();
}
singletons.put(klass, supplier);
}
static {
// add creation expressions for several classes;
// instances will not be created until needed
declareSingleton(ThingOne.class, () -> new ThingOne());
declareSingleton(ThingTwo.class, () -> new ThingTwo(123));
}
I'm not sure if this is what you want but it might contain some ideas.
Edit: I've just realized a problem of using the Class itself as a key: it causes the class to be loaded even if it is not needed during a particular program run. Using a String key would avoid loading unneeded classes, but increases fragility. This is another argument against using a map for all this.

How to Avoid Constructor calling During Object Creation?

I want to avoid the constructor calling during object creation in java (either default constructor or user defined constructor) . Is it possible to avoid constructor calling during object creation???
Thanks in advance......
Simply extract the intialization logic that you want to avoid into another method called init. You can not avoid calling exactly one constructor.
No matter what pattern or strategy you use, at some point your will need to call a constructor if you want to create an object.
Actually, its possible under some circumstances by using classes from the JVM implementation (which do not belong to the JRE API and are implemenation specific).
One example here http://www.javaspecialists.eu/archive/Issue175.html
It should also be possible using sun.misc.Unsafe.allocateInstance() (Java7)
Also, the constructor is apparently bypassed when using the clone()-method to create a copy of an object (and the class doesn't override clone to implement it different from the Object.clone() method).
All of these possibilities come with strings attached and should be used carefully, if at all.
You can mock the constructors of a class. They will still be called, but not executed. For example, the following JUnit+JMockit test does that:
static class CodeUnderTest
{
private final SomeDependency someDep = new SomeDependency(123, "abc");
int doSomething(String s)
{
someDep.doSomethingElse(s);
return someDep.getValue();
}
}
static final class SomeDependency
{
SomeDependency(int i, String s) { throw new RuntimeException("won't run"); }
int getValue() { return -1; }
}
#Test
public void mockEntireClassIncludingItsConstructors()
{
new NonStrictExpectations() {
#Mocked SomeDependency mockDep;
{ mockDep.getValue(); result = 123; }
};
int result = new CodeUnderTest().doSomething("testing");
assertEquals(123, result);
}

Categories

Resources