Reduce visibility when implementing interface in Java - java

I would like to design class A implements interface C and reduce the visibility of a method (declared in C)to make it secure from outer world, make one of the methods in interface implemented in class A as private (reducing visibility in class A). I have to do this for security reason, how can I do this, is there a workaround. We do know that by default, the interface has public members. But there is no option for me, can someone help me. Thanks in advance.
--
So , there is no way, to have a class implement method from interface and make it private. And all classes that implement any interface's method will always have public methods?

No, you can't reduce the visibility of a method in an interface. What would you expect to happen if someone wrote:
C foo = new A();
foo.methodDeclaredPrivateInA();
? As far as the compiler is concerned, everything with a reference to an implementation of C has the right to call any methods within it - that's what Liskov's Substitution Principle is all about.
If you don't want to implement the whole of a public interface, don't implement it - or throw exceptions if you absolutely must.
It's also worth noting that the accessibility provided in source code is rarely a good security measure. If your class is running in a VM which in turn gets to determine its own permissions, anyone can make members visible via reflection.

You can't reduce the visibility of the method of an interface in Java. Is it acceptable for you to implement the method by throwing a java.lang.UnsupportedOperationException?

You cannot reduce visiblity because you could write something along the lines of
C newC = new A();

This approach worked for me. Any new function added to PrivateInterface would break still break PublicSampleClass
private interface PrivateInterface {
void fooBar();
}
public class PublicSampleClass {
private final listenerInterface = new PrivateInterface {
public void fooBar() {
PublicSampleClass.this.fooBar();
}
};
protected void fooBar() {
// Non public implementation
}
}

Related

Protect "default" methods from overriding

I'm looking for a solution, that allows to protect the default methods from inheritance. The easiest solution could be - extend from class and etc... but in my case it's not possible.
Can someone suggest how to solve this problem? Could there be any workarounds?
Atm I have following code, which needs to be reworked (if/any possible):
public interface MyInterface1 {
default boolean isA(Object obj) {
return (boolean) obj.equals("A") ? true : false;
}
default boolean isB(Object obj) {
return (boolean) obj.equals("B") ? true : false;
}
}
public class MyClass extends MyLogic implements MyInterface, MyInterface1 {
// this class allows to inherit methods from both interfaces,
// but from my perspective i'd like to use the methods from MyInterface1 as it is,
// with a 'protection' from inheritance. is that possible?
}
You seem to want a way to write your interface so that implementing classes cannot provide their own implementations of its default methods. There is no way to do this, and indeed it runs counter to the purpose of interfaces in general and default members in particular.
The point of default methods is to provide a way to add methods to existing interfaces without instantly breaking all their existing implementations. Generally speaking, this is a binary compatibility issue, not a functionality issue. There's no particular reason to suppose in general that default implementations can provide the intended functionality, but without them, even old code that doesn't rely on the new methods at all is incompatible with interface revisions that add methods.
I think you have a factoring issue. Rather than trying to force classes to provide a specific implementation of a specific method -- which cannot even refer to that class's members, except possibly others defined by the same interface -- you should provide the common methods in a class of their own. After all, since you want all classes involved to provide identical implementations, it doesn't matter which class's implementations you actually use. Moreover, there is therefore no particular usefulness in marking any given class as providing implementations of the well-known methods.
Example:
public class MyImplementation1 {
public static boolean isA(Object obj) {
return obj.equals("A");
}
public static isB(Object obj) {
return obj.equals("B");
}
}
// Wherever needed, use as MyImplementation1.isA(o), etc.
You can do this even if you want these pre-baked implementations to operate in terms of the other methods of your interface. In that case, just add an argument to the fixed methods that provides the object to operate on. Perhaps that's what the obj arguments in your example were supposed to be; in that case, this may be closer to what you're after:
public interface MyInterface3 {
public String someInterfaceMethod();
}
public class MyImplementation2 {
public static boolean isA(MyInterface3 subject) {
return subject.someInterfaceMethod().equals("A");
}
public static boolean isB(MyInterface3 subject) {
return subject.someInterfaceMethod().equals("B");
}
}
You can't. At least if you restrict yourself to a pure-java-compiler solution.
And the reason is because it was not designed to do that: the purpose is to add new methods to existing interface (like java.util.Collection) without breaking the implementations. That way, we have sort(), stream(), forEach() on Collection.
If you were to allow such thing (forbidding implementation), then it would means a change in the interface would result in a compilation error for implementation (because they would override the method, method that would been rendered final). That was not the purpose.
There are several other options to achieve that, depending on your need:
Abstract class with final method being the previously default method.
Testing the default behavior using unit testing.
Testing the possible implementation and check they don't override it.
The last case can probably be done easily with Reflections: you would have to list all implementations, and check for each interface's default method that there is no overriding using Reflections.
I take it you mean you want to write a class that uses the default methods of an interface, but does not inherit them.
In your example code, you attempted to use the default methods by implementing the interface. When you implement an interface, by design you also inherit all its methods. This is the Liskov Substitution Principle. By implementing the interface you are telling your users that all instances of your class are substitutable for instances of the interface. But if the interface default methods weren't inherited, this wouldn't be true, so you would be lying to users of your class.
To have your class use the interface's default methods without inheriting them, don't implement the interface! Instead, use a helper class that does:
public interface MyInterface1 {
default boolean isA(Object obj) {
return obj.equals("A"); // or "A".equals(obj) to avoid NullPointerException
}
default boolean isB(Object obj) {
return obj.equals("B");
}
}
public class MyClass extends MyLogic implements MyInterface {
private static class Helper implements MyInterface1 {
void doSomeWork() {
// do something that calls isA() and isB()...
}
}
public void someMethodOfMyClass() {
// ...
Helper.doSomeWork();
// ...
}
}
No, This is not possible due to the way java implements the interface (pun intended). For more information as to the reason for this, see the answers to this question Why is "final" not allowed in Java 8 interface methods?
However here are some other ways to guide a developer not to override a default method:
A source code comment
//Do not inherit please
A javadoc comment

Creating an implementing class that reuses objects of other implementations of the same interface

I want to create a class that does not implement any method of an interface, but extends any implementation of A with it's own methods.
Let's assume we have the following:
public interface A {
public void a();
}
and
public class B implements A {
#override
public void a() {
System.out.println("a");
}
}
I now want to create a class C that also implements A and takes another random implementation of A:
public class C implements A {
public C(A a) {
//what do I need to do with a here?
}
public void c() {
System.out.println("c");
}
}
Now if I have the following:
A b = new B();
A c = new C(b);
c.a();
The output should be "a".
I can't just
public class C extends B {
...
as C is supposed to be able to work with any implementation of A, not just B.
I also can't
public class C implements A {
private a;
public C(A a) {
this.a = a;
}
#override
public void a() {
a.a();
}
public void c() {
System.out.println("c");
}
}
since that would mean that I have to redirect every single interface method and rewrite C whenever something changes with A.
Is there any way to handle that problem in Java?
For another example, replace A: List; B: ArrayList; C: FooList; a(): size()
What you're looking for is a dynamic proxy, which automatically implements all the methods of an interface by delegating to a concrete implementation of this interface. That's not trivial, but not so complex to do either, using Java's Proxy class.
A concrete example of such a proxy, which "adds" methods to any instance of PreparedStatement by wrapping it, can be found at https://github.com/Ninja-Squad/ninja-core/blob/master/src/main/java/com/ninja_squad/core/jdbc/PreparedStatements.java
Unfortunately, there's no way to do it in Java, other than your last code snippet. Various IDEs will help you with the code generation, though, and marking all methods #override will mean that you'll get a warning or an error if your implementation of C doesn't exactly match A's interface.
For Eclipse (and, apparently, IntelliJ), see the "Generate Delegate Methods" command.
This is probably not going to immediately help you, but if you used Java 8, you could solve this with defender methods, which are methods implemented in the interface.
You would then, for each existing implementation class, add your own class which extends the class and implements your additional interface with the defender methods. The methods would be "mixed into" your class.
Java 8 is just around the corner, though, so it is not a far-off solution. Oracle has promised it will release it by the end of this quarter, meaning in less than a month and a half at the latest.
Is there any way to handle that problem in Java?
Basically, no.
What you are describing a wrapper class that delegates calls to the wrapped method. The only way you can implement that (in regular Java) is to implement all of the methods and have them make the calls.
Another alternative would be to use the Proxy class ... which will effectively generate a dynamic proxy. The problem is that this requires an InvocationHandler that will (I guess) use reflection to make the call to the wrapped object. It is complicated and won't be efficient.
If your goal is simply to avoid writing code, I think this is a bad idea. If your goal is to writing the same code over and over (e.g. because you have lots of exampled of C for a given A), then consider coding an abstract class for the C classes that deals with the wrappering / delegation.
It would also be possible to generate the wrapper class C from nothing, using the BCEL library or similar. But that's an even worse idea (IMO).

Does Java allow use of an instance of the current class in its definition?

Does Java allow the use of an instance of the current class in its definition?
Example:
public class Component
{
Component()
{
// some code
}
public void method()
{
Component comp=new Component();
// some code
}
}
I know that it does not result in compile-time errors. I find the self-reference a bit confusing though. Does it mean that Java's semantics allows cyclic definition of classes?
i think you thought about something like this...
Running this leads to
Exception in thread "main" java.lang.StackOverflowError
public class AClass {
private AClass aClass;
public AClass() {
this.aClass = new AClass();
this.aClass.printHello();
}
private void printHello() {
System.out.println("Hello");
}
public static void main(final String[] args) {
new AClass();
}
}
I've not needed recursive code like this. But i think there could be some use cases.
It is important to have an abort criteria to prevent endless loop and the StackOverflowError.
To answer your question, i would say Java allows cylic instantiation.
It's perfectly legal to use / create instance of the same type on the defining class, there is no cyclic definition added.
Compilers usually do a first pass examining all the methods on a class, the actual method implementation code generation is done later once the compiler knows about all the methods available on all the clases.
It's not a cyclic definition.
Cyclic definition is when two or more classes reference each other in a cyclic manner.
But even that would compile, though may lead to execution problems.
It is rather a "use ahead" definition, this is how I would call it.
You define a class and in its method you use a reference to the same class.
It is a bit contradictory - before you use a class you should completely define it.
A method of a class is a part of its definition.
Where as in a method you reference a class instance as if the class was already defined.
I agree it is confusing, but Java let you do this.
Think of a singleton.
Often there is a static method that returns the class instance.
The same problem.

#MustOverride annotation?

In .NET, one can specify a "mustoverride" attribute to a method in a particular superclass to ensure that subclasses override that particular method.
I was wondering whether anybody has a custom java annotation that could achieve the same effect. Essentially what i want is to push for subclasses to override a method in a superclass that itself has some logic that must be run-through. I dont want to use abstract methods or interfaces, because i want some common functionality to be run in the super method, but more-or-less produce a compiler warning/error denoting that derivative classes should override a given method.
I don't quite see why you would not want to use abstract modifier -- this is intended for forcing implementation by sub-class, and only need to be used for some methods, not all. Or maybe you are thinking of C++ style "pure abstract" classes?
But one other thing that many Java developers are not aware of is that it is also possible to override non-abstract methods and declare them abstract; like:
public abstract String toString(); // force re-definition
so that even though java.lang.Object already defines an implementation, you can force sub-classes to define it again.
Ignoring abstract methods, there is no such facility in Java. Perhaps its possible to create a compile-time annotation to force that behaviour (and I'm not convinced it is) but that's it.
The real kicker is "override a method in a superclass that itself has some logic that must be run through". If you override a method, the superclass's method won't be called unless you explicitly call it.
In these sort of situations I've tended to do something like:
abstract public class Worker implements Runnable {
#Override
public final void run() {
beforeWork();
doWork();
afterWork();
}
protected void beforeWork() { }
protected void afterWork() { }
abstract protected void doWork();
}
to force a particular logic structure over an interface's method. You could use this, for example, to count invocations without having to worry about whether the user calls super.run(), etc.
... and if declaring a base class abstract is not an option you can always throw an UnsupportedOperationException
class BaseClass {
void mustOverride() {
throw new UnsupportedOperationException("Must implement");
}
}
But this is not a compile-time check of course...
I'm not sure which attribute you're thinking about in .NET.
In VB you can apply the MustOverride modifier to a method, but that's just the equivalent to making the method abstract in Java. You don't need an attribute/annotation, as the concept is built into the languages. It's more than just applying metadata - there's also the crucial difference that an abstract method doesn't include any implementation itself.
If you do think there's such an attribute, please could you say which one you mean?
Android has a new annotation out as announced in the Google I/O 2015:
#callSuper
More details here:
http://tools.android.com/tech-docs/support-annotations
If you need some default behaviour, but for some reason it should not be used by specializations, like a implementation of a logic in a non abstract Adapter class just for easy of prototyping but which should not be used in production for instance, you could encapsulate that logic and log a warning that it is being used, without actually having to run it.
The base class constructor could check if the variable holding the logic points to the default one. (writing in very abstract terms as I think it should work on any language)
It would be something like this (uncompiled, untested and incomplete) Java (up to 7) example:
public interface SomeLogic {
void execute();
}
public class BaseClass {
//...private stuff and the logging framework of your preference...
private static final SomeLogic MUST_OVERRIDE = new SomeLogic() {
public void execute() {
//do some default naive stuff
}
};
protected SomeLogic getLogic() { return MUST_OVERRIDE; }
//the method that probably would be marked as MustOverride if the option existed in the language, maybe with another name as this exists in VB but with the same objective as the abstract keyword in Java
public void executeLogic() {
getLogic().execute();
}
public BaseClass() {
if (getLogic() == MUST_OVERRIDE) {
log.warn("Using default logic for the important SomeLogic.execute method, but it is not intended for production. Please override the getLogic to return a proper implementation ASAP");
}
}
}
public GoodSpecialization extends BaseClass {
public SomeLogic getLogic() {
//returns a proper implementation to do whatever was specified for the execute method
}
//do some other specialized stuff...
}
public BadSpecialization extends BaseClass {
//do lots of specialized stuff but doesn't override getLogic...
}
Some things could be different depending on the requirements, and clearly simpler, especially for languages with lambda expressions, but the basic idea would be the same.
Without the thing built in, there is always some way to emulate it, in this example you would get a runtime warning in a log file with a home-made-pattern-like-solution, that only your needs should point if it is enough or a more hardcore bytecode manipulation, ide plugin development or whatever wizardry is needed.
I've been thinking about this.
While I don't know of any way to require it with a compile error, you might try writing a custom PMD rule to raise a red-flag if your forgot to override.
There are already loads of PMD rules that do things like reminding you to implement HhashCode if you choose to override equals. Perhaps something could be done like that.
I've never done this before, so I'm not the one to write a tutorial, but a good place to start would be this link http://techtraits.com/programming/2011/11/05/custom-pmd-rules-using-xpath/ In this example, he basically creates a little warning if you decide to use a wildcard in an import package. Use it as a starting point to explore how PMD can analyze your source code, visit each member of a hierarchy, and identify where you forgot to implement a specific method.
Annotations are also a possibility, but you'd have to figure out your own way to implement the navigation through the class path. I believe PMD already handles this. Additionally, PMD has some really good integration with IDEs.
https://pmd.github.io/

Is there any way to modify the value of a `private static final` field in Java from outside the class?

I know this is normally rather stupid, but don't shoot me before reading the question. I promise I have a good reason for needing to do this :)
It's possible to modify regular private fields in java using reflection, however Java throws a security exception when trying to do the same for final fields.
I'd assume this is strictly enforced, but figured I'd ask anyway just in case someone had figured out a hack to do this.
Let's just say I have an external library with a class "SomeClass"
public class SomeClass
{
private static final SomeClass INSTANCE = new SomeClass()
public static SomeClass getInstance(){
return INSTANCE;
}
public Object doSomething(){
// Do some stuff here
}
}
I essentially want to Monkey-Patch SomeClass so that I can execute my own version of doSomething(). Since there isn't (to my knowledge) any way to really do that in java, my only solution here is to alter the value of INSTANCE so it returns my version of the class with the modified method.
Essentially I just want to wrap the call with a security check and then call the original method.
The external library always uses getInstance() to get an instance of this class (i.e. it's a singleton).
EDIT: Just to clarify, getInstance() is called by the external library, not my code, so just subclassing won't solve the issue.
If I can't do that the only other solution I can think of is to copy-paste entire class and modify the method. This isn't ideal as I'll have to keep my fork up to date with changes to the library. If someone has something a little more maintainable I'm open to suggestions.
It is possible. I've used this to monkeypatch naughty threadlocals that were preventing class unloading in webapps. You just need to use reflection to remove the final modifier, then you can modify the field.
Something like this will do the trick:
private void killThreadLocal(String klazzName, String fieldName) {
Field field = Class.forName(klazzName).getDeclaredField(fieldName);
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
int modifiers = modifiersField.getInt(field);
modifiers &= ~Modifier.FINAL;
modifiersField.setInt(field, modifiers);
field.set(null, null);
}
There is some caching as well around Field#set, so if some code has run before it might not necessarily work....
Any AOP framework would fit your needs
It would allow you to define a runtime override for the getInstance method allowing you to return whatever class suits your need.
Jmockit uses the ASM framework internally to do the same thing.
You can try the following. Note: It is not at all thread safe and this doesn't work for constant primitives known at compile time (as they are inlined by the compiler)
Field field = SomeClass.class.getDeclareField("INSTANCE");
field.setAccessible(true); // what security. ;)
field.set(null, newValue);
You should be able to change it with JNI... not sure if that is an option for you.
EDIT: it is possible, but not a good idea.
http://java.sun.com/docs/books/jni/html/pitfalls.html
10.9 Violating Access Control Rules
The JNI does not enforce class, field,
and method access control restrictions
that can be expressed at the Java
programming language level through the
use of modifiers such as private and
final. It is possible to write native
code to access or modify fields of an
object even though doing so at the
Java programming language level would
lead to an IllegalAccessException.
JNI's permissiveness was a conscious
design decision, given that native
code can access and modify any memory
location in the heap anyway.
Native code that bypasses
source-language-level access checks
may have undesirable effects on
program execution. For example, an
inconsistency may be created if a
native method modifies a final field
after a just-in-time (JIT) compiler
has inlined accesses to the field.
Similarly, native methods should not
modify immutable objects such as
fields in instances of
java.lang.String or java.lang.Integer.
Doing so may lead to breakage of
invariants in the Java platform
implementation.
If you really must (though for our problem I'd suggest you use the solution of CaptainAwesomePants) you could have a look at JMockIt. Although this is intented to be used in unit tests if allows you to redefine arbitrary methods. This is done by modifying the bytecode at runtime.
I will preface this answer by acknowledging that this is not actually an answer to your stated question about modifying a private static final field. However, in the specific example code mentioned above, I can in fact make it so that you can override doSomething(). What you can do is to take advantage of the fact that getInstance() is a public method and subclass:
public class MySomeClass extends SomeClass
{
private static final INSTANCE = new MySomeClass();
public SomeClass getInstance() {
return INSTANCE;
}
public Object doSomething() {
//Override behavior here!
}
}
Now just invoke MySomeClass.getInstance() instead of SomeClass.getInstance() and you're good to go. Of course, this only works if you're the one invoking getInstance() and not some other part of the unmodifiable stuff you're working with.
with mockito is very simple:
import static org.mockito.Mockito.*;
public class SomeClass {
private static final SomeClass INSTANCE = new SomeClass();
public static SomeClass getInstance() {
return INSTANCE;
}
public Object doSomething() {
return "done!";
}
public static void main(String[] args) {
SomeClass someClass = mock(SomeClass.getInstance().getClass());
when(someClass.doSomething()).thenReturn("something changed!");
System.out.println(someClass.doSomething());
}
}
this code prints "something changed!"; you can easily replace your singleton instances. My 0.02$ cents.
If there is no external hack available (at least I am not aware of) I would have hacked the class itself. Change the code by adding the security check you want. As such its an external library, you won't be taking the updates regularly, also not many update happens anyway. Whenever that happens I can happily re-do it as it is not a big task anyway.
Here, your problem is good-old Dependency Injection (aka Inversion of Control). Your goal should be to inject your implementation of SomeClass instead of monkeypatching it. And yes, this approach requires some changes to your existing design but for the right reasons (name your favorite design principle here) - especially the same object should not be responsible for both creating and using other objects.
I assume the way you're using SomeClass looks somewhat like this:
public class OtherClass {
public void doEverything() {
SomeClass sc = SomeClass.geInstance();
Object o = sc.doSomething();
// some more stuff here...
}
}
Instead, what you should do is first create your class that implements the same interface or extends SomeClass and then pass that instance to doEverything() so your class becomes agnostic to implementation of SomeClass. In this case the code that calls doEverything is responsible for passing in the correct implementation - whether be the actual SomeClass or your monkeypatched MySomeClass.
public class MySomeClass() extends SomeClass {
public Object doSomething() {
// your monkeypatched implementation goes here
}
}
public class OtherClass {
public void doEveryting(SomeClass sc) {
Object o = sc.doSomething();
// some more stuff here...
}
}

Categories

Resources