Escaping of this reference in java multithreading [duplicate] - java

I would appreciate help in understanding the following from 'Java Concurrency in Practice':
Calling an overrideable instance method(one that is neither
private nor final) from the constructor can also allow the
this reference to escape.
Does 'escape' here simply mean that we may probably be calling an instance method,before the instance is fully constructed?
I do not see 'this' escaping the scope of the instance in any other way.
How does 'final' prevent this from happening?Is there some aspect of 'final' in instance creation that I am missing?

It means calling code outside the class, and passing this.
That code will assume that the instance is fully initialized, and may break if it isn't.
Similarly, your class might assume that some methods will only be called after the instance is fully initialized, but the external code is likely to break those assumptions.
final methods cannot be overridden, so you can trust them to not pass this around.
If you call any non-final method in the constructor for a non-final class, a derived class might override that method and pass this anywhere.
Even when you call final methods, you still need to make sure that they are safely written – that they do not pass this anywhere, and that themselves don't call any non-final methods.

"Escape" means that a reference to the partially-constructed this object might be passed to some other object in the system. Consider this scenario:
public Foo {
public Foo() {
setup();
}
protected void setup() {
// do stuff
}
}
public Bar extends Foo implements SomeListener {
#Override protected void setup() {
otherObject.addListener(this);
}
}
The problem is that the new Bar object is being registered with otherObject before its construction is completed. Now if otherObject starts calling methods on barObject, fields might not have been initialized, or barObject might otherwise be in an inconsistent state. A reference to the barObject (this to itself) has "escaped" into the rest of the system before it's ready.
Instead, if the setup() method is final on Foo, the Bar class can't put code in there that will make the object visible before the Foo constructor finishes.

I believe the example is something like
public class Foo {
public Foo() {
doSomething();
}
public void doSomething() {
System.out.println("do something acceptable");
}
}
public class Bar extends Foo {
public void doSomething() {
System.out.println("yolo");
Zoom zoom = new Zoom(this); // at this point 'this' might not be fully initialized
}
}
Because the super constructor is always called first (either implicitly or explicitly), the doSomething will always get called for a child class. Because the above method is neither final nor private, you can override it in a child class and do whatever you want, which may conflict with what Foo#doSomething() was meant to do.

Per secure coding
Example BAD code:
final class Publisher {
public static volatile Publisher published;
int num;
Publisher(int number) {
published = this;
// Initialization
this.num = number;
// ...
}
}
If an object's initialization (and consequently, its construction) depends on a security check within the constructor, the security check can be bypassed when an untrusted caller obtains the partially initialized instance. See rule OBJ11-J. Be wary of letting constructors throw exceptions for more information.
final class Publisher {
public static Publisher published;
int num;
Publisher(int number) {
// Initialization
this.num = number;
// ...
published = this;
}
}
Because the field is nonvolatile and nonfinal, the statements within
the constructor can be reordered by the compiler in such a way that
the this reference is published before the initialization statements
have executed.
Correct code:
final class Publisher {
static volatile Publisher published;
int num;
Publisher(int number) {
// Initialization
this.num = number;
// ...
published = this;
}
}
The this reference is said to have escaped when it is made available
beyond its current scope. Following are common ways by which the this
reference can escape:
Returning this from a non-private, overridable method that is invoked from the constructor of a class whose object is being
constructed. (For more information, see rule MET05-J. Ensure that
constructors do not call overridable methods.)
Returning this from a nonprivate method of a mutable class, which allows the caller to manipulate the object's state indirectly. This
commonly occurs in method-chaining implementations; see rule VNA04-J.
Ensure that calls to chained methods are atomic for more information.
Passing this as an argument to an alien method invoked from the constructor of a class whose object is being constructed.
Using inner classes. An inner class implicitly holds a reference to the instance of its outer class unless the inner class is declared
static.
Publishing by assigning this to a public static variable from the constructor of a class whose object is being constructed.
Throwing an exception from a constructor. Doing so may cause code to be vulnerable to a finalizer attack; see rule OBJ11-J. Be wary of
letting constructors throw exceptions for more information.
Passing internal object state to an alien method. This enables the method to retrieve the this reference of the internal member object.
This rule describes the potential consequences of allowing the this
reference to escape during object construction, including race
conditions and improper initialization. For example, declaring a field
final ordinarily ensures that all threads see the field in a fully
initialized state; however, allowing the this reference to escape
during object construction can expose the field to other threads in an
uninitialized or partially initialized state. Rule TSM03-J. Do not
publish partially initialized objects, which describes the guarantees
provided by various mechanisms for safe publication, relies on
conformance to this rule. Consequently, programs must not allow the
this reference to escape during object construction.
In general, it is important to detect cases in which the this
reference can leak out beyond the scope of the current context. In
particular, public variables and methods should be carefully
scrutinized.

Related

How is my private member getting set to null?

I have been programming java professionally for more than ten years. This is one of the weirdest bugs I've ever tried to track down. I have a private member, I initialize it and then it changes to null all by itself.
public class MyObject extends MyParent
{
private SomeOtherClass member = null;
public MyObject()
{
super();
}
public void callbackFromParentInit()
{
member = new SomeOtherClass();
System.out.println("proof member initialized: " + member);
}
public SomeOtherClass getMember()
{
System.out.println("in getMember: " + member);
return member;
}
}
Output:
proof member initialized: SomeOtherClass#2a05ad6d
in getMember: null
If you run this code, obviously it will work properly. In my actual code there are only these three occurrences (five if you count the printlns) in this exact pattern.
Have I come across some bug in the JVM? Unless I'm wrong, the parent class can't interfere with a private member, and no matter what I put between the lines of code I've shown you, I can't change the value of member without using the identifier "member".
This happens because of the order in which member variables are initialized and constructors are called.
You are calling callbackFromParentInit() from the constructor of the superclass MyParent.
When this method is called, it will set member. But after that, the subclass part of the object initialization is performed, and the initializer for member is executed, which sets member to null.
See, for example:
What's wrong with overridable method calls in constructors?
State of Derived class object when Base class constructor calls overridden method in Java
Using abstract init() function in abstract class's constructor
In what order constructors are called and fields are initialized is described in paragraph 12.5 of the Java Language Specification.
Assignment of null to field member happens after executing parent constructor.
The fix is to change:
private SomeOtherClass member = null;
to:
private SomeOtherClass member;
Never, never ever call a non final method from the superclass' constructor.
It's considered bad practice, precisely because it can lead to nasty, hard-to-debug errors like the one you're suffering.
Perform initialization of a class X within X's constructor. Don't rely on java's initialization order for hierarchies. If you can't initialize the class property i.e. because it has dependencies, use either the builder or the factory pattern.
Here, the subclass is resetting the attribute member to null, due to superclass and subclass constructors and initializer block execution order, in which, as already mentioned, you shouldn't rely.
Please refer to this related question for concepts regarding constructors, hierarchies and implicit escaping of the this reference.
I can only think about sticking to a (maybe incomplete) set of rules/principles to avoid this problem and others alike:
Only call private methods from within the constructor
If you like adrenaline and want to call protected methods from within the constructor, do it, but declare these methods as final, so that they cannot be overriden by subclasses
Never create inner classes in the constructor, either anonymous, local, static or non-static
In the constructor, don't pass this directly as an argument to anything
Avoid any transitive combination of the rules above, i.e. don't create an anonymous inner class in a private or protected final method that is invoked from within the constructor
Use the constructor to just construct an instance of the class, and let it only initialize attributes of the class, either with default values or with provided arguments

Constructor class thread safety in Java reflection

Using Java reflection, one can instantiate an object of a class, even via a private constructor, e.g. for
public class MyClass
{
private MyClass(Object p1, String p2)
{
// Constructor with no modifications to static code
}
}
one can do (in the same or any other class, exception handling omitted for simplification)
public static final Constructor myClass;
static
{
myClass = MyClass.class.getConstructor(Object.class, String.class);
myClass.setAccessible(true);
}
and then create new instances of MyClass like
myClass.newInstance(new Object(), "Test");
Is the above call to newInstance() thread-safe, given that myClass is static?
Calling Constructor.newInstance() does not seem to be strictly thread-safe; at least in my openjdk-6 implementation I find a class sun.reflect.NativeConstructorAccessorImpl having a field defined as private int numInvocations; and later on this line of code: if (++numInvocations > ReflectionFactory.inflationThreshold()) { - which may certainly behave otherwise as expected.
Also, in the Constructor class itself, the method acquireConstructorAccessor() is documented with "NOTE that there is no synchronization used here".
But the dodgy behaviour does not seem to result in an overall unexpected behavior, only doing things repeatedly/unnecessarily, thus calling newInstance() in parallel would NOT result in something being screwed up.
Obviously, you can still mess things up with what's done within the instance constructor.
Yes, the class instance is static, and the constructor is thread safe, as long as it is not doing anything non-thread safe with the static context of the object.

final static methods exam

I have been studying for my Software Development course and came across the question from a sample:
"Why does it make no sense to have both the static and final modifiers in front of a Java method?"
I have had a bit of a research and everywhere I go it says it is not bad practice and there are good reasons for doing so - for example, this stackoverflow question:
Is it a bad idea to declare a final static method?
So, is this question itself nonsensical or is there a legitimate answer to this question?
(There are no given solutions to this sample paper)
static methods cannot be overriden since they're associated not with an instance of class, but with the class itself. For example, this is how you'd usually call static method:
MyClass.myStaticMethod()
And this is how you call an instance method:
new MyClass().myInstanceMethod()
final modifier is used with methods to disallow their override in extending classes.
Because a static method cannot be overridden. There is therefore no point in marking it final.
Note however that static final variables (which are, oddly, therefore NOT variables because they cannot change) are very useful because their values can be inlined by the compiler.
Static methods can be sort of overridden (though that's not the technical term), since it is resolved at runtime, searching upwards in class chain until it's found. But this "feature" is probably a mistake; people don't use it, people don't know about it, we should pretend it doesn't exist.
From the Java Language Spec:
A class method is always invoked without reference to a particular
object. It is a compile-time error to attempt to reference the current
object using the keyword this or the keyword super.
So you cannot override a static method because it does not belong to an instance. So, the keywords this and super are not avaliable and you cannot use virtual method invocation. And if you cannot use virtual method invocation then the final keyword is of no use.
I like to think that the compiler sees method declarations like this:
public class SomeClass{
// public static classMethod() becomes
public static [final] void classMethod(){
//...
}
// and public void instanceMethod() becomes
public void instanceMethod(SomeClass this, Object super){
//....
}
}
public class SomeOtherClass extends SomeClass{
// overrides
#Override
public void instanceMethod(SomeOtherClass this, SomeClass super){
//...
}
}
And you call SomeClass instance = new SomeOtherClass().instanceMethod(); then its called the instanceMethod() of SomeOtherClass.
So the compiler does not need to copy method bodys and just pass the reference to the current object in the thread. So, when you use virtual method invocation, in fact you are calling the instanceMethod with a reference to the current object (this) and the body method of the current class is what is called.

A call to a static method within the parameter list of super() is valid in Java. Why?

Let's look at the following code snippet in Java.
package trickyjava;
class A
{
public A(String s)
{
System.out.println(s);
}
}
final class B extends A
{
public B()
{
super(method()); // Calling the following method first.
}
private static String method()
{
return "method invoked";
}
}
final public class Main
{
public static void main(String[] args)
{
B b = new B();
}
}
By convention, the super() constructor in Java must be the first statement in the relevant constructor body. In the above code, we are calling the static method in the super() constructor parameter list itself super(method());.
It means that in the call to super in the constructor B(), a method is being
called BEFORE the call to super is made! This should be forbidden by the compiler but it works nice. This is somewhat equivalent to the following statements.
String s = method();
super(s);
However, it's illegal causing a compile-time error indicating that "call to super must be first statement in constructor". Why? and why it's equivalent super(method()); is valid and the compiler doesn't complain any more?
The key thing here is the static modifier. Static methods are tied to the class, instance methods (normal methods) are tied to an object (class instance). The constructor initializes an object from a class, therefore the class must already have been fully loaded. It is therefore no problem to call a static method as part of the constructor.
The sequence of events to load a class and create an object is like this:
load class
initialize static variables
create object
initialize object <-- with constructor
object is now ready for use
(simplified*)
By the time the object constructor is called, the static methods and variables are available.
Think of the class and its static members as a blueprint for the objects of that class. You can only create the objects when the blueprint is already there.
The constructor is also called the initializer. If you throw an exception from a constructor and print the stack trace, you'll notice it's called <init> in the stack frame. Instance methods can only be called after an object has been constructed. It is not possible to use an instance method as the parameter for the super(...) call in your constructor.
If you create multiple objects of the same class, steps 1 and 2 happen only once.
(*static initializers and instance initializers left out for clarity)
Yep, checking the JVM spec (though admittedly an old one):
In the instance init method, no reference to "this" (including the implicit reference of a return) may occur before a call to either another init method in the same class or an init method in the superclass has occurred.
This is really the only real restriction, so far as I can see.
The aim of requiring the super constructor to be invoked first is to ensure that the "super object" is fully initialized before it is used (It falls short of actually enforcing this because the super constructor can leak this, but that's another matter).
Calling a non-static method on this would allow the method to see uninitialized fields and is therefore forbidden. A static method can only see these fields if it is passed this as argument. Since accessing this and super is illegal in super constructor invocation expressions, and the call to super happens before the declaration of any variables that might point to this, allowing calls to static methods in super constructor invocation expressions is safe.
It is also useful, because it allows to compute the arguments to the super constructor in an arbitrarily complex manner. If calls to static methods weren't allowed, it would be impossible to use control flow statements in such a computation. Something as simple as:
class Sub extends Super {
Sub(Integer... ints) {
super(Arrays.asList(ints));
}
}
would be impossible.
This is one situation where the java syntax hides what's really going on, and C# makes it a bit clearer.
In C# your B would look like
class B : A {
public B() : base(method()) {
}
private static String method() {
return "method invoker";
}
}
Although the java syntax places super(method) within the constructor it's not really called there: All the parent initialization is run before your subclass constructor. The C# code shows this a little more clearly; by placing super(method()) at the first line of the java constructor you're simply telling java to use the parameterized constructor of the super class rather than the parameterless version; this way you can pass variables to the parent constructor and they'll be used in the initialization of the parent level fields before your child's constructor code runs.
The reason that super(method()) is valid (as the first line in a java constructor) is because method() is being loaded with the static elements--before the non-static ones, including the constructors--which allows it to be called not only before B(), but before A(String) as well. By saying
public B() {
String s = method();
super(s);
}
you're telling the java compiler to initialize the super object with the default constructor (because the call to super() isn't the first line) and you're ready to initialize the subclass, but the compiler then becomes confused when it sees that you're trying to initialize with super(String) after super() has already run.
A call to super is a must in java to allow the parent to get initalized before anything with child class starts.
In the case above, if java allows String s= method(); before the call to super, it opens up flood gate of things that can be done before a call to super. that would risk so many things, essentially that allows a half baked class to be used. Which is rightly not allowed. It would allow things like object state (some of which may belong to the parent) being modified before it was properly created.
In case of super(method()); call, we still adhere to the policy of completing parent initialization before child. and we can use a static member only, and static member of child classes are available before any child objects are created anyways. so the method is avilable and can be called.
OK..i think, this one could be relevant that, if we are calling some member with Super, then it first try to invoke in super class and if it doesn't find same one then it'll try to invoke the same in subclass.
PS: correct me if i'm wrong

Null Object When Passed Into An Anonymous Inner Class

When passing a final object (A String in the code below) it shows up as null when printed from the anonymous inner class. However, when a final value type or straight final String is passed in, its value is correctly displayed. What does final really mean in context of the anonymous inner class and why is the object passed null?
public class WeirdInners
{
public class InnerThing
{
public InnerThing()
{
print();
}
public void print(){
}
}
public WeirdInners()
{
final String aString = "argh!".toString();
final String bString = "argh!";
System.out.println(aString);
System.out.println(bString);
InnerThing inner =new InnerThing(){
public void print()
{
System.out.println("inner"+aString); // When called from constructor, this value is null.
System.out.println("inner"+bString); // This value is correctly printed.
}
};
inner.print();
}
public static void main(String[] args)
{
WeirdInners test1 = new WeirdInners();
}
}
This is very strange behavior to me because the expectation is that the String is an object, why does calling toString() change things?
Other info: this behavior is only observed using Java 1.4, not in Java 5. Any suggestions on a workaround? Not calling toString() on an existing String is fair enough, but since this is only an example, it has real world implications if I perform it on a non-String object.
If you check the section on compile-time constants in the JLS, you'll see that calling .toString() does make a difference. As does nonsense like prefixing with false?null+"":.
What is important here is the relative ordering of setting the fields that are closed over and the constructor. If you use -target 1.4 or later (which is not the default in 1.4!) then the fields will be copied before calling the super. With the spec before 1.3 this was illegal bytecode.
As is often the case in these cases, javap -c is useful to see what the javac compiler is doing. The spec is useful for understanding why (should you have sufficient patience).
My guess would be that you trigger undefined behaviour when the constructor of InnerThing() passes (implicitly) its this to the print method of an anonymous subclass of InnerThing while the object is not fully constructed. This this in turn relies on an implicit reference to the this of WierdInners.
Calling .toString() moves initialisation of aString from compile time to runtime. Why the undefined behaviour differs between Java 1.4 and 1.5 is a JVM implementation detail probably.
It is dangerous to invoke overridden methods from a superclass constructor, as they will be called before the subclass-part of the object is initialized.
Moreover, an inner class accessing final variables of an enclosing scope will actually access copies of those variables (that's why they need to be final), and these copied fields reside in the anonymous subclass.
I suspect the reason bString is treated differently is that its value is known at compile time, which allows the compiler to inline the field access in the subclass, making the time that field is initialized irrelevant.

Categories

Resources