Like so?
abstract public class BaseTask extends Runnable {
public BaseTask(ParamA aParam) {
// do something with aParam
StaticExecutorService.submit(this);
}
}
public class AbcTask extends BaseTask {
public ABC(ParamA aParam, ParamB bParam) {
super(aParam);
}
#Override
public void run() {
}
}
The class can then just be created and queued for execution by doing a
new AbcTask();
I'm not sure if this is ok because maybe it is still being constructed when ExecutorService decides to execute AbcTask?
If you don't recommend this for whatever reason, please state and elaborate.
Thanks
This might work (at least, I'm not familiar enough with Java to see why it wouldn't), but I would not recommend it as it introduces too strong a coupling: AbcTask would be tied to StaticExecutorService and would be less reusable than it could easily be. This will also make the AbcTask harder to test and debug.
Also, you're "overloading" the meaning of object construction by folding submission to an executor into it. What if, later on, you decide you want to do something to AbcTask objects in between constructing them and submitting them?
We should not use this until the constructor is completed.
An object is instantiated fully after completion of it's c'tor. so the object passed within StaticExecutorService might not be created fully and may not be usable.
I don't know if specification supports my above statement. but i feel so.
Hence, acc. to me it should be avoided.
Its tightly coupled
In Effective Java, Joshua Bloch explained why it is not a good practice to invoke a protected/public method from a constructor. See 2nd edition, CH-4: Constructors must not invoke overridable methods, directly or indirectly.
StaticExecutorService.submit(this);
Above line will invoke the public method run from the constructor, and this is not expected.
Explanation from the book: Constructors must not invoke overridable methods, directly or indirectly
If you violate this rule, program failure will result. The superclass constructor runs
before the subclass constructor, so the overriding method in the subclass will get
invoked before the subclass constructor has run. If the overriding method depends
on any initialization performed by the subclass constructor, the method will not
behave as expected.
In your example it will probably work but as the call to super() has to be the first in child classes of BaseTask this means that the constructor won't be able to perform any operation before the submission of the task.
From you sample, the second parameter cannot be used since the task will be submitted before you can assign it to an attribute.
If we consider the following code:
public class MyTask extends BaseTask {
public ABC(ParamA aParam, String name) {
super(aParam);
this.name = name == null ? "Default Value" : name;
}
#Override
public void run() {
System.out.println("Name length: "+ name.length());
}
}
Since run() can be called before the assignment of this.name the System.out line can end in NullPointerException
Related
A pattern I sometimes see is that a constructor might take either no argument or one argument. Now, I wonder whether the 'better' approach is to move common code to the most defined constructor - or to use the instance initializer in this case. For example, one way of always generating an ID for every class created:
public SomeClass(){
this("Hello");
}
public SomeClass(String s){
this.s = s;
this.id = generateId();
}
versus writing it like this:
{
this.id = generateId(); // method does not depend on the class
}
public SomeClass(){
this("Hello");
}
public SomeClass(String s){
this.s = s;
}
The reason for using the Instance Initializer would be because I want to always run the method when the class is created, and in the future someone else might change the class's constructors and forget to do this. Whilst it is less likely to remove the instance initializer (without realizing what you are doing).
But on the other hand, I am not sure how about readability in this case.
The examples are a bit contrived, not real-world examples.
The reason for using the Instance Initializer would be because I want
to always run the method when the class is created, and in the future
someone else might change the class's constructors and forget to do
this. Whilst it is less likely to remove the intance initializer
(without realising what you are doing).
Doing the one (using the Instance Initializer) or the other one (constructor) should not be used as trick to avoid coding error when the class is modified.
And anyway, why Initializer would give better insurance about it ?
You want to ensure that the constructor do what it designed to do ?
Writing an unit test that validates this behavior and that is automatically executed at each build.
That's all.
I think the reasonable solution here:
private final Whatever id = generateId();
In other words:
make sure the compiler knows that this should be initialized (so use final)
and instead of using an init block (rather uncommon) simply do initialize once, "in place"
I have never seen a use of instnace initializer in real life. (I actually did see it and played with it for a bit in one of theoretical questions on this site). In real life though you often can see a static initializer block:
public class Bla {
static {
//do something
}
....
}
As for common code what could be done is to have a method called init() that is called by all constructors. In your example it would look like
public SomeClass(){
this("Hello");
}
public SomeClass(String s){
init();
this.s = s;
}
private init() {
this.id = generateId(); // method does not depend on the class
}
I am maintaining some Java 8 code which looks like this:
Class Entity {
protected Model theModel;
public Entity() {
init();
}
protected void init() {
this.theModel = new Model();
}
}
Class Model {
}
Class SubModel extends Model {
}
main {
Entity newEntity = new Entity() {
#Override
protected void init() {
this.theModel = new SubModel();
}
};
}
The code currently compiles and runs correctly, but I now need to update it.
My question are:
How is the override of the init() method working at all, during the construction of the newEntity?
What is the correct terminology for this method override included in the object constructor statement?
My research so far suggests that Java cannot dynamically override methods - cannot do overrides on this basis, because method overrides are per-class not per-object. But this code snippet seems to show that Java can do it in practice?
UPDATE: Note that the creation of the newEntity in main creates an anonymous sub-class, and the init() method is being overridden for that anonymous sub-class only. This is explained better in the two excellent answers below.
As far as I can tell there is nothing special here, is just classical constructor chaining and polymorphism applied to virtual method invocations.
When you instantiate your anonymous class, it will automatically invoke its default constructor (which is automatically given by the compiler), before its default constructor succeeds it must first invoke its parent class default constructor, which in turn will invoke the init() method, which, since it has been overridden by your anonymous class, polymorphically, ends up calling the init method in the child class, which initializes the model to your SubModel instance.
Joshua Bloch has a few interesting arguments against this pattern in his famous book Effective Java, in the section "Item 17: Design and document for inheritance or else prohibit" he wrote:
“There are a few more restrictions that a class must obey to allow
inheritance. Constructors must not invoke overridable methods,
directly or indirectly. If you violate this rule, program failure will
result. The superclass constructor runs before the subclass
constructor, so the overriding method in the subclass will get invoked
before the subclass constructor has run. If the overriding method
depends on any initialization performed by the subclass constructor,
the method will not behave as expected. To make this concrete, here's
a class that violates this rule:”
He then proceeds to give an example which you would do well to study:
“Here's a subclass that overrides the overrideMe, method which is
erroneously invoked by Super's sole constructor:”
public class Super {
// Broken - constructor invokes an overridable method
public Super() {
overrideMe();
}
public void overrideMe() {
}
}
public final class Sub extends Super {
private final Date date; // Blank final, set by constructor
Sub() {
date = new Date();
}
// Overriding method invoked by superclass constructor
#Override public void overrideMe() {
System.out.println(date);
}
public static void main(String[] args) {
Sub sub = new Sub();
sub.overrideMe();
}
}
“You might expect this program to print out the date twice, but it
prints out null the first time, because the overrideMe method is
invoked by the Super constructor before the Sub constructor has a
chance to initialize the date field. Note that this program observes a
final field in two different states! Note also that if overrideMe had
invoked any method on date, the invocation would have thrown a
NullPointerException when the Super constructor invoked overrideMe.
The only reason this program doesn't throw a NullPointerException as
it stands is that the println method has special provisions for
dealing with a null argument.”
So, as you can see, and as Joshua Bloch explained so well, the risks lurk in the shadows: in the possibilities of what you can do in the overridden method, where you have license to touch instance variables that the constructor chain has not yet had a chance to initialize. The point is that you should not be allowed to touch the object state until it has been fully initialized by the constructor chain.
You might say that in your particular case that does not happen, since you are not illegally altering state and your overridden method is protected, not public, but the problem is that any person touching this code needs a very clear understanding of all these things happening under the hood, happening in places other than your current code. During maintenance it is easy to make a serious mistake, particularly when you or some other developer, comes back here to make changes, possibly months or even years after this was originally defined, and having lost context of all these dangers somebody introduces a bug that will be really hard to find and fix.
If it is in fact exactly as you are showing us, and there is no significant part of the picture missing, then the code that you have to maintain is bad, and maintenance of bad code is very troublesome.
Invoking an overridable from within a constructor is legal, but it is very bad practice, because the overridable will be invoked on a descendant whose constructor has not yet been invoked, which is catastrophic. It may not matter in trivial examples, where descendants have empty constructors, but it is bound to cause major trouble later, when things become more complicated, and a descendant suddenly one day needs to have a non-empty constructor.
And with the passage of time things do tend to become more complicated.
A halfway decent IDE would have issued a big fat warning on the invocation of the overridable from within the constructor. This in turn means that the code was written with an insufficient number of warnings enabled, which probably means that it is full of problems of this kind.
The correct terminology for this method override included in the object constructor is: Wrong.
You cannot correct this without some major refactoring. Either the model needs to be passed as a constructor parameter, or the constructor must live with the fact that the model cannot be known at all during construction.
Your question about "dynamically" overriding methods is a bit strange, and it is probably unnecessarily complicating things. Virtual method dispatching is done internally by means of a virtual method table. Each class has its own virtual method table, which never changes. However, when a constructor executes, the this pointer points to the actual (descendant) instance, so the virtual method table in effect is that of the descendant. So, when the constructor calls an overridable, the overridable of the descendant is invoked.
That's different from C++, where the virtual method table in effect at construction time is the virtual method table of the class declaring the constructor, (irrespective of whether it has been subclassed,) so when you call a virtual method from within a C++ constructor you are not invoking any overriding methods.
I have some code I want to run every time any method is invoked in a specific Java class, but don't want to touch the actual method bodies. This is because there are a lot of methods that change frequently, and the people programming these methods shouldn't have to worry about adding my code to every method.. even if it is just a single line that calls another method.
I can't think of a way to achieve this with inheritance, so I was wondering if it is possible with reflection? Or even at all?
It's possible to get a list of methods in a class, inspect their properties and even invoke them. But I'm not seeing anything that lets you attach extra code, such as an event handler for example. Maybe Java is the wrong language for something like this..
This is very common behavior, where Aspect Oriented Programming is definitely the right thing to use.
But I also get impressed with how the famous CMS does it.
For each class which contains the concrete method around, you can have a property (List of methods) which contains the code you want to execute before the method call.
You can write a registerBeforeCall(Method m) method which takes a method and adds to teh list.
Your method should contain a for loop at the first line(which goes through the list of methods) and invoke each of the method one by one.
Do not forget to put a try and catch and ignore the exception if there is any in the invocations.
For e.g. :
public void myActualMethod(){
for(Method m : registeredMethodsToCallBeforeActualCode){
m.invoke();
}
//my actual code
// here you can also write a for loop to execute all the methods which you want to call after your actual code is executed.
}
This approach is not very special, but is widely use, when you do not choose AOP.
one way to implement it by inheritance is:
public SuperClass {
public void doSomething() {
doBefore();
doSpecific();
doAfter();
}
protected abstract void doSpecific();
}
public SubClass extends SuperClass {
protected void doSpecific() {
System.out.println("Do specific implementation....");
}
}
public static void main(String[] args) {
SuperClass clazz = new SubClass();
clazz.doSomething();
}
I have an existing class into which I want to add a method. But I want the method to be called only from a specific method from a specific class. Is there any way that I can prevent that call from other classes/methods?
For example, I have an existing class A
public final class A
{
//other stuff available for all classes/methods
//I want to add a method that does its job only if called from a specific method of a class, for example:
public void method()
{
//proceed if called from Class B.anotherMethod() else throw Exception
}
}
One way of doing this is getting the StackTrace inside the method() and then confirming the parent method?
What I am looking for is a solution that is more clean and advisable solution like a pattern or something.
To be honest, you have painted yourself into a corner here.
If classes A and B are not related and not members of the same package, then visibility won't solve the problem. (And even if it did, reflection can be used to subvert the visibility rules.)
Static code analysis won't solve the problem if the code can use reflection to call the method.
Passing and checking B.this as an extra parameter to A.method(...) doesn't help because some other class C could pass a B instance.
This leaves only the stacktrace approach1... or giving up and relying on the good sense of the programmer2 not to call methods that they shouldn't.
The ideal solution is to revisit the design and/or coding decisions that got you into this mess.
1 - See other answers for examples that use annotations, a security manager, etc to conceal the stacktrace stuff from the application programmer. But note that under the hood you are adding probably hundreds, possibly thousands of instructions overhead per method call.
2 - Do not underestimate the programmer's good sense. Most programmers, when they see advice not to call some method, are likely to follow that advice.
The right way to do this would be a SecurityManager.
Define a permission which all code which wants to call A.method() has to have, and then make sure only B and A have that permission (this also means that no class has AllPermission).
In A, you check this with System.getSecurityManager().checkPermission(new BMethodPermission()), and in B you call the method inside of AccessController.doPrivileged(...).
Of course, this requires that a security manager is installed (and it uses suitable policies) - if it isn't, all code is trusted and everyone can call everything (if necessary, with Reflection).
You might consider using an interface. If you're passing in the calling class, you can confirm that the class is of the appropriate type.
Alternatively, if you're using Java, you can use "default" or "package" level access (e.g. void method() vs. public void method()). This will allow your method to be called by any class inside the package and does not require that you pass the class to the method.
The only way to check for sure at run time is to take a stack trace. Even if its private you can access the method via reflections.
A simpler way to do this would be to check usages in your IDE. (provided its not called via reflections)
As others have mentioned, using the stack trace is one way to implement the functionality that you are looking for. Generally, if one needs to "block" callers from a public method, it could be a sign of poor design. As a rule of thumb, use access modifiers that restrict the scope as much as possible. However, making a method package-private or protected is not always an option. Sometimes, one may want to group some classes in a separate package. In that case, the default (package-private) access is too restrictive, and it usually does not make sense to subclass, so protected is not helpful either.
If restricting calling to certain classes is desired, you can create a method like:
public static void checkPermission(Class... expectedCallerClasses) {
StackTraceElement callerTrace = Thread.currentThread().getStackTrace()[3];
for (Class expectedClass : expectedCallerClasses) {
if (callerTrace.getClassName().equals(expectedClass.getName())) {
return;
}
}
throw new RuntimeException("Bad caller.");
}
Using it is very simple: just specify what class(es) can call the method. For example,
public void stop() {
checkPermission(ShutdownHandler.class);
running = false;
}
So, if the stop method gets called by a class other than ShutdownHandler, checkPermission will throw an IllegalStateException.
You may wonder why checkPermission is hard-coded to use the fourth element of the stack trace. This is because Thread#getStackTrace() makes the most recently called method the first element. So,
getStackTrace()[0] would be the call to getStackTrace itself.
getStackTrace()[1] would be the call to checkPermission.
getStackTrace()[2] would be the call to stop.
getStackTrace()[3] would be the method that called stop. This is what we are interested in.
You mentioned that you want methods to be called from a specific class and method, but checkPermission only checks for class names. Adding the functionality to check for method names requires only a few modifications, so I'm going to leave that as an exercise.
Make proper use of protected
The standard way to do this in java is to put Class B and Class A in the same package (maybe a subpackage of your current application) and use the default visibility.
The default java visibility is "package-private" which means everything in that package can see your method, but nothing outside that package can access it.
See Also:
Is there a way to simulate the C++ 'friend' concept in Java?
Assuming that you only need to apply this restriction to classes within your project, static analysis could work for you - for example an ArchUnit test:
package net.openid.conformance.archunit;
import com.google.gson.JsonElement;
import com.tngtech.archunit.base.DescribedPredicate;
import com.tngtech.archunit.core.domain.AccessTarget;
import com.tngtech.archunit.core.domain.JavaClass;
import com.tngtech.archunit.core.domain.JavaClasses;
import com.tngtech.archunit.core.importer.ClassFileImporter;
import com.tngtech.archunit.lang.ArchRule;
import net.openid.conformance.testmodule.OIDFJSON;
import org.junit.Test;
import static com.tngtech.archunit.core.domain.JavaCall.Predicates.target;
import static com.tngtech.archunit.core.domain.JavaClass.Predicates.assignableTo;
import static com.tngtech.archunit.core.domain.properties.HasName.Predicates.*;
import static com.tngtech.archunit.core.domain.properties.HasOwner.Predicates.With.owner;
import static com.tngtech.archunit.lang.conditions.ArchPredicates.are;
import static com.tngtech.archunit.lang.syntax.ArchRuleDefinition.noClasses;
public class PreventGetAs {
#Test
public void doNotCallJsonElementGetAs() {
JavaClasses importedClasses = new ClassFileImporter().importPackages("net.openid.conformance");
JavaClasses allExceptOIDFJSON = importedClasses.that(DescribedPredicate.not(nameContaining("OIDFJSON")));
ArchRule rule = noClasses().should().callMethodWhere(
target(nameMatching("getAs[^J].*")) // ignores getAsJsonObject/getAsJsonPrimitive/etc which are fine
.and(target(owner(assignableTo(JsonElement.class)))
)).because("the getAs methods perform implicit conversions that might not be desirable - use OIDFJSON wrapper instead");
rule.check(allExceptOIDFJSON);
}
}
You can do it by using annotations and reflection. I will report a similar case, i.e. the case where you can let the method being called only by specific methods from extenal classes. Suppose that the class that must be "protected" by a whatsoever invocation of the its public methods is Invoked, while Invoker is the class tha has a method enabled to invoke one or more methods from Invoked. Then, you can do something like reported in the following.
public class Invoked{
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.METHOD)
public static #interface CanInvoke{}
public void methodToBeInvoked() {
boolean canExecute=false;
try {
//get the caller class
StackTraceElement element = (new Throwable()).getStackTrace()[1];
String className = element.getClassName();
Class<?> callerClass = Class.forName(className);
//check if caller method is annotated
for (Method m : callerClass.getDeclaredMethods()) {
if (m.getName().equals(methodName)) {
if(Objects.nonNull(m.getAnnotation(EnabledToMakeOperationRemoved.class))){
canExecute = true;
break;
}
}
}
} catch (SecurityException | ClassNotFoundException ex e) {
//In my case does nothing
}
if(canExecute){
//do something
}
else{
//throw exception
}
}
}
and the Invoker class is
public class Invoker{
private Invoked i;
#Invoked.CanInvoke
public void methodInvoker(){
i.methodToBeInvoked();
}
}
Note that the method that is enabled to invoke is annotated with the CanInvoke annotation.
The case that you requested is similar. You annotate the classes/method that cannot call the public method and then you set to true the canExecute variable only if the method/class is not annotated.
You can use a tool like Macker and add it to your build process to check some rules are respected, like
<?xml version="1.0"?>
<macker>
<ruleset name="Simple example">
<access-rule>
<deny>
<from class="**Print*" />
<to class="java.**" />
</deny>
</access-rule>
</ruleset>
</macker>
It will NOT prevent you from writing wrong code but if you use Maven or another build system it can raise an error during your build process.
This tools work at a "class" level not at a "method" level but I do not see the point of preventing the call of only one method from a certain class ...
I realise your use case states 'specific method in specific class', but I don't think you can reliably solve this at design time (and I can't think of a use case where this would have to be enforced anyway).
The following example creates an easy design time solution for restricting the access of a class' method to a particular class. It can, however, be easily extended to multiple allowed classes.
It is achieved by defining a public inner class with a private constructor that acts as a key to the method at hand. In the following example the class Bar has a method that should only be called from an instance of the Foo class.
Class Foo:
public class Foo
{
public Foo()
{
Bar bar = new Bar();
bar.method(new FooPrivateKey());
}
public class FooPrivateKey
{
private FooPrivateKey()
{ }
}
}
Class Bar:
public class Bar
{
public Bar()
{
}
public void method(FooPrivateKey fooPrivateKey)
{
if(fooPrivateKey == null)
{ throw new IllegalArgumentException("This method should only be called from the Foo class.");}
//Do originally intended work.
}
}
I don't think this is by any means safe for things like reflection or even things like FooPrivateKey.class.newInstance(), but this will at least warn the programmer a little more obtrusively than a simple comment or documentation, while you don't have to look in to more complicated things like what was suggested by people like Roberto Trunfio and Ronan Quillevere (which are perfectly viable answers as well, just too complicated for most situations in my opinion).
I hope this is sufficient for your use case.
Referring to my earlier question on incompletely constructed objects, I have a second question. As Jon Skeet pointed out, there's an implicit memory barrier in the end of a constructor that makes sure that final fields are visible to all threads. But what if a constructor calls another constructor; is there such a memory barrier in the end of each of them, or only in the end of the one that got called in the first place? That is, when the "wrong" solution is:
public class ThisEscape {
public ThisEscape(EventSource source) {
source.registerListener(
new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
});
}
}
And the correct one would be a factory method version:
public class SafeListener {
private final EventListener listener;
private SafeListener() {
listener = new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
}
}
public static SafeListener newInstance(EventSource source) {
SafeListener safe = new SafeListener();
source.registerListener(safe.listener);
return safe;
}
}
Would the following work too, or not?
public class MyListener {
private final EventListener listener;
private MyListener() {
listener = new EventListener() {
public void onEvent(Event e) {
doSomething(e);
}
}
}
public MyListener(EventSource source) {
this();
source.register(listener);
}
}
Update: The essential question is that is this() guaranteed to actually call the private constructor above (in which case there would be the barrier where intended and everything would be safe), or is it possible that the private constructor gets inlined into the public one as an optimization to save one memory barrier (in which case there wouldn't be a barrier until in the end of the public constructor)?
Are the rules of this() defined precisely somewhere? If not, then I think we must assume that inlining chained constructors is allowed, and probably some JVMs or maybe even javacs are doing it.
I think it is safe as java memory model states that:
Let o be an object, and c be a constructor for o in which a final
field f is written. A freeze action on final field f of o takes place
when c exits, either normally or abruptly. Note that if one
constructor invokes another constructor, and the invoked constructor
sets a final field, the freeze for the final field takes place at the
end of the invoked constructor.
An object is considered to be completely initialized when its constructor finishes.
This applies also for chained constructors.
If you have to register in the constructor define the listener as a static inner class. This is safe.
Your second version is not correct, because it is allowing the 'this' reference to escape from the construction process. Having 'this' escape invalidates the initialization safety guarantees that give final fields their safety.
To address the implicit question, the barrier at the end of construction only happens at the very end of object construction. The intuition one reader offered about inlining is a useful one; from the perspective of the Java Memory Model, method boundaries do not exist.
EDIT After the comment that suggested the compiler inlining the private constructor (I had not thought of that optimization) chances are that the code will be unsafe. And the worst part of unsafe multithreaded code is that is seems to work, so you are better off avoiding it completely. If you want to play different tricks (you do really want to avoid the factory for some reason) consider adding a wrapper to guarantee the coherence of data in the internal implementation object and register in the external object.
My guess is that it will be fragile but ok. The compiler cannot know whether the internal constructor will be called only from within other constructors or not, so it has to make sure that the result would be correct for code calling only the internal constructor, so whatever mechanism it uses (memory barrier?) has to be in place there.
I would guess that the compiler would add the memory barrier at the end of each and every constructor. The problem is still there: you are passing the this reference to other code (possibly other threads) before it is fully constructed --that is bad--, but if the only ´construction´ that is left is registering the listener, then the object state is as stable as it will ever be.
The solution is fragile in that some other day, you or some other programmer may need to add another member to the object and may forget that the chained constructors is a concurrency trick and may decide to initialize the field in the public constructor, and in doing so will add a hard to detect potential data race in your application, so I would try to avoid that construct.
BTW: The guessed safety may be wrong. I don't know how complex/smart the compiler is, and whether the memory barrier (or the like) is something it could try to optimize away... since the constructor is private the compiler does have enough information to know that it is only called from other constructors, and that is enough information to determine that the synchronization mechanism is not necessary in the internal constructor...
Escaping object reference in c-tor can publish an incompletely constructed object. This is true even if the publication is the last statement in the constructor.
Your SafeListener might not behave ok in a concurrent environment, even if c-tor inlining is performed (which I think it's not - think about creating objects using reflection by accessing private c-tor).