How to properly cleanup incorrectly initialized object? - java

I was asked this question in an interview.
There is a class, lets call it A. It has a default constructor and it initializes 2 different connections in its constructor.
Methods initDB & initSocket creates a DB connection and a socket connection and saves them in an instance field. They are just an example. They could also be file open or anything else.
Lets say a client instantiates an instance of this class. Now initDB executed successfully, but initSocket threw exception. So the object creation was aborted. But the DB connection was not closed prior to the exception. This resulted in a resource leak. How would I tackle this kind of resource leak?
E.g.
class A {
public A(){
this.dbConnection = initDB();
this.socketConnection = initSocket(); // throws exception
}
}
My initial answer was that I would not initialize these in constructor but in a separate init(). He countered by suggesting that this could be a legacy class, and I have been asked to maintain this. In which case I need to somehow clear the resource leak. How would I approach this problem?
I got stumped because instance creation threw an exception I lost any kind of reference to those connection fields. So I cannot call close() on them. But they will still be present in the OS level (this is my guess).
Note 1
As stated by Interviewer, I cannot change the behavior of the already written constructor. I can extend or do something around it, but cannot change the code.
Note 2
I think interviewer was not looking for explicitly any code that would handle this scenario. Would any JMX stuff help? I took a jibe at it & then we moved on. For those who think this is a very good question, I think interviewer knew this is not a general practice and probably would not be able to answer.

We have a few options here...
Box the thing off somewhere else. It's clearly problematic legacy code. Perhaps this "blob" which has access control issues can be moved into something some other process that can communicate with the rest of the system via RPC. You are better off doing this if the system is horribly broken. You can extend it other ways, such as composition; but if it's so sealed off you can't get it it, then you're boned
Use byte code modification. You could do this and you could get enough leverage to get what you need. ByteBuddy would come in handy for this. I wouldn't do this personally but hey, sometimes desperate measures call for desperate solutions...
If you can influence initDB, then you can decorate the return value with something else. For example, let's supposed it was some from some base class we did control or some other method we controlled, then we could perhaps do something like this
Connection initDb() {
try {
this.wrappedProvider.initDb();
} catch(Exception e) {
// .. destroy the connection...
}
}
... and then since you can influence this, you can change the effective semantics of it.
Can you influence the "Connection" of "A"? How does it get "A"? If it gets it from some DI container or something you can influence, then you can sub out the implementation for that class for something that "times out" if not talked to or initialized in some given time. Hacky, sure but without more info that's the best we're going to get...

Solution 1:
Provided that:
You can extend class A, and then use instances of class B instead,
method initSocket is overridable (not final nor private)
field dbConnection is accessible from class B (not private)
You can override method initSocket to close the dbConnection in case of an exception:
#Override
protected Socket initSocket() {
boolean ok = false;
try {
Socket result = super.initSocket();
ok = true;
return result;
} finally {
if (!ok) {
dbConnection.close();
}
}
}
Solution 2:
Provided that:
You can extend class A
method initDb is overridable (not final nor private)
You can wrap your A object in another class, and save the connection so that it can be closed in case of an exception:
class B {
private static ThreadLocal<Connection> CONNECTION = new ThreadLocal<>();
private final A delegate;
public B() {
boolean ok = false;
try {
delegate = new A() {
#Override
protected Connection initDb() {
Connection result = super.initDb();
CONNECTION.set(result);
return result;
}
};
ok = true;
} finally {
if (!ok) {
Connection cnt = CONNECTION.get();
if (cnt != null) {
cnt.close();
}
}
CONNECTION.set(null);
}
}
}

Related

Multithreading behaviour with Static Members

How multithreading behaves in case of static members? Like in case of Singleton Class, if I try to create instance in a static block and in the static method, I return the instance and two threads try to execute getInstance() at the same time..how will this behave internally as static are loaded only one time
public class SingleTonUsingStaticInitialization {
private static SingleTonUsingStaticInitialization INSTANCE = null;
static {
try {
INSTANCE = new SingleTonUsingStaticInitialization();
} catch (Exception e) {
e.printStackTrace();
}
}
private SingleTonUsingStaticInitialization() {
}
public static SingleTonUsingStaticInitialization getInstance() {
return INSTANCE;
}
}
This specific example?
Threadingwise it's fine. Style wise it's deplorable. Do NOT write catch blocks like that. It also means if an exception does occur (it can't here - your constructor is empty), your code will dump half of the info to system error, and then continue, with a null reference instance of an instance of Singleton - causing other code to spit out NullPointerExceptions (because code just keeps going, as you caught the exception instead of letting it happen). If you treat all exceptions in this fashion, a single error will cause hundreds of errors in your logs, all irrelevant except the first one.
Once you take care of this exception handling issue, you can make the variable final, and no longer assign null to it. While you're at it, make the whole class final. It effectively is already (as you only have a private constructor):
public final class Singleton {
private static final Singleton INSTANCE = new Singleton();
private Single() {}
public static Singleton getInstance() {
return INSTANCE;
}
The reason this works out when 2 threads simultaneously invoke getInstance, is the classloader mechanism itself: The Classloader guarantees that any given class is never loaded more than once by the same loader, even if 2 threads would simultaneously require this (the classloader will synchronize/lock to avoid this situation), and the initialization process (the static block - which was needlessly convoluted, as the example above shows) is similarly guarded and cannot possibly occur twice.
That's the only freebie you get: For static methods as a general rule, all threads can just run the same method all simultaneously if they want to. And here they do - it's just that the initialization (which includes the ... = new Singleton(); part) is gated to occur only once.
NB: If you must do more complex things, make helper methods:
public final class Singleton {
private static Singleton INSTANCE = create();
private Singleton(Data d) {
// do stuff with 'd'
}
private static Singleton create() {
Data d;
try {
d = readStuffFromDataIncludedInMyJar();
} catch (IOException e) {
throw new Error("states.txt is corrupted", e);
}
return new Singleton(d);
}
}
This:
Keeps code simple - static initializers are a thing, but fairly exotic java.
Makes your code easier to test.
It's an internal file; if that is missing/broken, that's about as likely / as problematic as one of your class files having gone for a walk. An Error is warranted here. This cannot possibly occur unless you wrote a bug or messed up a build, and hard crashing with a clear exception telling you precisely what's wrong is exactly what you want to happen in that case, not for code to blindly continue in a state where half of your app is overwritten with gobbledygook due to a disk drive crash or what not. Best to just conclude everything's borked, say so, and stop running.
You are safe, in the sense that getInstance will return the same instance to multiple threads. This is guaranteed by The JLS, which is the only place you should delegate your understanding to. Specifically, that chapter says:
For each class or interface C, there is a unique initialization lock LC
And goes on further to say that:
The procedure for initializing C is then as follows:
Synchronize on the initialization lock, LC, for C. This involves waiting until the current thread can acquire LC
In plain english, only a single thread can initialize that static field. Period.
The release of that lock gives proper happens-before guarantees between the action in the static block and any thread that uses that static field. This is implied from the same chapter, from:
An implementation may optimize this procedure by eliding the lock acquisition in step 1 (and release in step 4/5) when it can determine that the initialization of the class has already completed, provided that, in terms of the memory model, all happens-before orderings that would exist if the lock were acquired, still exist when the optimization is performed
Or, again, in plain english, whatever happens in that static block will be visible to all reading threads.
To that end, you will have a proper tool to remove that static block, via a so called "constant dynamic". The infrastructure for it is already in place, but javac still does not use it. You can read more here about it. Some projects already use that - if you have the proper jdk, for example jacoco does it.
See the fine points made in the Answer by rzwitserloot.
Here is similar code to the code seen there, but adapted to use an enum as your singleton. Many folks recommended an enum as the ideal way to define a singleton in Java.
Thread-safety is guaranteed because of the same class loader behavior discussed in the other Answer. The enum is loaded once, and only once, per class loader when the class first loads.
If you have multiple threads accessing the single object defined by this enum, the first thread to reach the point where this class is loaded will cause our enum object to be instantiated with its constructor method running. The other remaining threads will block on their attempt to access the enum object until the enum class finishes loading and its one and only named enum object finishes its construction. The JVM juggles all this contention automatically, with no further coding needed by us. All that behavior is guaranteed by the Java specifications.
package org.vaadin.example;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
public enum AppContext
{
INSTANCE;
private String wording;
AppContext ( )
{
try
{
readStuffFromDataIncludedInMyJar();
}
catch ( IOException e )
{
throw new Error( "Failed to load from text file. Message # 7a608ddf-8c5f-4f77-a9c9-5ab852fde5b1." , e );
}
}
private void readStuffFromDataIncludedInMyJar ( ) throws IOException
{
Path path = Paths.get( "/Users/basilbourque/example.txt" );
String read = Files.readAllLines( path ).get( 0 );
this.wording = read;
System.out.println( "read = " + read );
}
public static void main ( String[] args )
{
System.out.println( AppContext.INSTANCE.toString() );
}
}
When run.
read = Wazzup?
INSTANCE

Passing this in constructor

I came across some JMS calling code that initializes the JMS session inside of its constructor. The calling code implements the ExceptionListener interface and passes a reference to this to the connection factory object, as shown below:
public class JmsCode implements ExceptionListener {
private static final Logger logger = LoggerFactory.getLogger(JmsCode.class);
public JmsCode(String url, String username, String password, String trustStorePath, char[] trustStorePassword) throws JMSException {
ActiveMQSslConnectionFactory connectionFactory = new ActiveMQSslConnectionFactory(url);
connectionFactory.setUserName(username);
connectionFactory.setPassword(password);
connectionFactory.setTrustStore(trustStorePath);
connectionFactory.setTrustStorePassword(new String(trustStorePassword));
connectionFactory.setExceptionListener(this);
Connection connection = connectionFactory.createConnection();
connection.start();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
}
#Override
public void onException(JMSException e) {
logger.error("Unexpected JMS exception caught", e);
}
}
I am wondering if it is safe to pass a reference to this from the JmsCode constructor given that the object hasn't been fully constructed yet. I came across a similar question which had me reading up on IBM's article on not publishing this during construction. While I agree with their reasoning, I am not sure if it applies in this case since the only thing the exception listener is doing is logging via a static and final member. Is the code above safe (ignoring someone else being tempted to change the exception listener method to use some instance state of the object)?
This is in fact unsafe publishing, and it's theoretically possible for another object to see this one in an inconsistent state.
That said, while this isn't a good pattern (and it's just shown here to demonstrate ExceptionListener), the logic of the constructor shows that the class is in fact fully constructed by the time that the this reference escapes (because it has nothing to construct), and so in this exact case there's nothing that can go wrong.
Whether it is safe or not depends on where that reference to this can escape to. If, as a consequence of this call, this could be read by another thread, then it is not safe.
If you want to ensure an instance is completely initialized for safe publication and you want to publish it, a constructor isn't the right place to publish it. Instead, you'll need to create a Factory object or a static factory method which can construct the object safely and then publish it before returning it to the caller.
It is completely safe. You are just passing the this reference, not using anything in the this scope.
Something will go wrong on that iff the .setExceptionListener(this) method performs something else than being a setter.

Can we create and use our own interface instead of defined by the java?

Q1 : (removed)
Q2 : try-with-resource to create own resource implement AutoCloseable interface and override close() method.
From javadoc
Any object that implements java.lang.AutoCloseable, which includes all objects which implement java.io.Closeable, can be used as a resource.
So, here I created a simple program MyAuto.java
class Demo implements AutoCloseable {
public void show() {
System.out.println("show");
}
public void close() {
System.out.println("close from demo");
}
}
class MyAuto {
public static void main(String[] args) {
try(Demo d = new Demo()) {
int x = 10/0;
d.show();
}catch(ArithmeticException e) {
System.out.println(e);
}
}
}
This program runs fine. :) and giving output
close from demo : as expected, no matters exception occurs, d will be closed.
But my question is I didn't write any code that close this resource, I simply put a print statement. What here actually closing a resource mean ? Assigning null to reference variable of resource or anything else ?
Or JVM runs any other method after running close() behind the scene.
And finally the most important question..
Q3 : In the above scenario if I add my own interface AutoCloseable
interface AutoCloseable {
void close() throws Exception;
}
It gives compile time error on compiling MyAuto.java
error: incompatible types: try-with-resources not applicable to variable type
try(Demo d = new Demo()) {
^
(Demo cannot be converted to AutoCloseable).
So, please give me answer why it's happening. Why can't we create and use our own Interfaces instead of provided by java. What is difference between my interface and the one predefined, although both are same.
What is difference between my interface and the one predefined, although both are same.
They're not the same. Not by a long shot.
The AutoCloseable required for try-with-resources is java.lang.AutoCloseable. Your custom AutoCloseable doesn't come from that package, so Java isn't going to respect it.
Above all, introducing that would not be the best approach, since it'll only lead to confusing semantics and a bad experience later down the road, even if you elected to have your interface extend java.lang.AutoCloseable for whatever reason.
In the same vein...
...I didn't write any code that close this resource, I simply put a print statement. What here actually closing a resource mean ? Assigning null to reference variable of resource or anything else ? Or JVM runs any other method after running close() behind the scene.
The interface can't enforce anything like that. All it can do is provide a mechanism that, if well-implemented, will behave as you expect.

Solving LazyInitializationException via ignorance

There are countless questions here, how to solve the "could not initialize proxy" problem via eager fetching, keeping the transaction open, opening another one, OpenEntityManagerInViewFilter, and whatever.
But is it possible to simply tell Hibernate to ignore the problem and pretend the collection is empty? In my case, not fetching it before simply means that I don't care.
This is actually an XY problem with the following Y:
I'm having classes like
class Detail {
#ManyToOne(optional=false) Master master;
...
}
class Master {
#OneToMany(mappedBy="master") List<Detail> details;
...
}
and want to serve two kinds of requests: One returning a single master with all its details and another one returning a list of masters without details. The result gets converted to JSON by Gson.
I've tried session.clear and session.evict(master), but they don't touch the proxy used in place of details. What worked was
master.setDetails(nullOrSomeCollection)
which feels rather hacky. I'd prefer the "ignorance" as it'd be applicable generally without knowing what parts of what are proxied.
Writing a Gson TypeAdapter ignoring instances of AbstractPersistentCollection with initialized=false could be a way, but this would depend on org.hibernate.collection.internal, which is surely no good thing. Catching the exception in the TypeAdapter doesn't sound much better.
Update after some answers
My goal is not to "get the data loaded instead of the exception", but "how to get null instead of the exception"
I
Dragan raises a valid point that forgetting to fetch and returning a wrong data would be much worse than an exception. But there's an easy way around it:
do this for collections only
never use null for them
return null rather than an empty collection as an indication of unfetched data
This way, the result can never be wrongly interpreted. Should I ever forget to fetch something, the response will contain null which is invalid.
You could utilize Hibernate.isInitialized, which is part of the Hibernate public API.
So, in the TypeAdapter you can add something like this:
if ((value instanceof Collection) && !Hibernate.isInitialized(value)) {
result = new ArrayList();
}
However, in my modest opinion your approach in general is not the way to go.
"In my case, not fetching it before simply means that I don't care."
Or it means you forgot to fetch it and now you are returning wrong data (worse than getting the exception; the consumer of the service thinks the collection is empty, but it is not).
I would not like to propose "better" solutions (it is not topic of the question and each approach has its own advantages), but the way that I solve issues like these in most use cases (and it is one of the ways commonly adopted) is using DTOs: Simply define a DTO that represents the response of the service, fill it in the transactional context (no LazyInitializationExceptions there) and give it to the framework that will transform it to the service response (json, xml, etc).
What you can try is a solution like the following.
Creating an interface named LazyLoader
#FunctionalInterface // Java 8
public interface LazyLoader<T> {
void load(T t);
}
And in your Service
public class Service {
List<Master> getWithDetails(LazyLoader<Master> loader) {
// Code to get masterList from session
for(Master master:masterList) {
loader.load(master);
}
}
}
And call this service like below
Service.getWithDetails(new LazyLoader<Master>() {
public void load(Master master) {
for(Detail detail:master.getDetails()) {
detail.getId(); // This will load detail
}
}
});
And in Java 8 you can use Lambda as it is a Single Abstract Method (SAM).
Service.getWithDetails((master) -> {
for(Detail detail:master.getDetails()) {
detail.getId(); // This will load detail
}
});
You can use the solution above with session.clear and session.evict(master)
I have raised a similar question in the past (why dependent collection isn't evicted when parent entity is), and it has resulted an answer which you could try for your case.
The solution for this is to use queries instead of associations (one-to-many or many-to-many). Even one of the original authors of Hibernate said that Collections are a feature and not an end-goal.
In your case you can get better flexibility of removing the collections mapping and simply fetch the associated relations when you need them in your data access layer.
You could create a Java proxy for every entity, so that every method is surrounded by a try/catch block that returns null when a LazyInitializationException is catched.
For this to work, all your entities would need to implement an interface and you'd need to reference this interface (instead of the entity class) all throughout your program.
If you can't (or just don't want) to use interfaces, then you could try to build a dynamic proxy with javassist or cglib, or even manually, as explained in this article.
If you go by common Java proxies, here's a sketch:
public static <T> T ignoringLazyInitialization(
final Object entity,
final Class<T> entityInterface) {
return (T) Proxy.newProxyInstance(
entityInterface.getClassLoader(),
new Class[] { entityInterface },
new InvocationHandler() {
#Override
public Object invoke(
Object proxy,
Method method,
Object[] args)
throws Throwable {
try {
return method.invoke(entity, args);
} catch (InvocationTargetException e) {
Throwable cause = e.getTargetException();
if (cause instanceof LazyInitializationException) {
return null;
}
throw cause;
}
}
});
}
So, if you have an entity A as follows:
public interface A {
// getters & setters and other methods DEFINITIONS
}
with its implementation:
public class AImpl implements A {
// getters & setters and other methods IMPLEMENTATIONS
}
Then, assuming you have a reference to the entity class (as returned by Hibernate), you could create a proxy as follows:
AImpl entityAImpl = ...; // some query, load, etc
A entityA = ignoringLazyInitialization(entityAImpl, A.class);
NOTE 1: You'd need to proxy collections returned by Hibernate as well (left as an excersice to the reader) ;)
NOTE 2: Ideally, you should do all this proxying stuff in a DAO or in some type of facade, so that everything is transparent to the user of the entities
NOTE 3: This is by no means optimal, since it creates a stacktrace for every access to an non-initialized field
NOTE 4: This works, but adds complexity; consider if it's really necessary.

Java - How to restrict method calling from a specific method

I have a peculiar requirement where I need ensure that only a particular method from one class is allowed to call a public (non-static) method from a second class. Inheritance cannot be used.
One option is to use StackTrace as follows:
ClassA.java
package org.rnd.stack;
public class ClassA {
public void methodA() throws IllegalAccessException {
Exception fake = new Exception("FAKE-IGNORE");
StackTraceElement[] stack = fake.getStackTrace();
StackTraceElement st = stack[1];
if ("org.rnd.stack.ClassB".equals(st.getClassName())
&& "methodB".equals(st.getMethodName())) {
System.out.println("You are allowed to call");
} else {
throw new IllegalAccessException("You are not allowed to call");
}
}
}
ClassB.java
package org.rnd.stack;
public class ClassB {
public void methodB() throws IllegalAccessException {
new ClassA().methodA();
}
public void illegalMethod() throws IllegalAccessException {
new ClassA().methodA();
}
public static void main(String[] args) {
try {
new ClassB().methodB();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Now the above solution works fine, but due to quality control in code audit I need to come up with another (or rather) better solution. Is there a better way to achieve this?
The right thing to do would be to revisit your requirement. A method that can only be called by certain other code paths is not compatible with public. The general best practice is to use package-private to prevent external callers, and accept that any code in the package could call the method, but won't because you or your team is auditing it.
Method visibility is ultimately not a secure solution to preventing execution; someone has your .class files and the ability to execute them on a machine, they can do just about anything they want. You shouldn't spend too much time trying to lock down method calls. Instead, document the intent of the method clearly (e.g. "Helper function for methodB(), please do not use elsewhere.") and trust the people developing with you know what they're doing. You can even give the method a clear name, like dangerousMethodBForInternalUseOnly() if you really want to beat people over the head about it.
You may also be interested in dependency-injection, which is a design pattern that uses the type system to protect (not prevent) people from executing dangerous code. Here's a couple of talks on Guice, a popular DI framework, that goes into more detail about the concept:
Google I/O 2009 - Big Modular Java with Guice
Java on Guice: Dependency Injection, the Java Way
All of that said, as an academic exercise here's one option for restricting method invocation to a fixed number of codepaths - rely on a shared secret. Add an Object secret field to your locked-down method, and cause the method to fail if the passed secret does not match a hard-coded value (private static final Object SECRET = new Object()). You can then use other mechanisms to share the secret only to code paths you allow (e.g. have a static initializer in your locked-down class publish it to classes you explicitly trust).
Obviously this can still be worked-around by a malicious developer, and it's pretty gross, but it would provide some sort of locking behavior assuming you can trust your locked-down class won't be changed without your knowledge.
A way to improve you method is that you don't need to create an exception to get the stacktrace, you can use the thread methods.
StackTraceElement[] stack = Thread.currentThread().getStackTrace();
Also maybe you want to use the class instead of handwriting the package. For example:
if (ClassB.class.getName().equals(st.getClassName())
&& "methodB".equals(st.getMethodName())) {
System.out.println("You are allowed to call");
} else {
throw new IllegalAccessException("You are not allowed to call");
}
Apart from that I don't know how you can do it better without changing your logic or using inheritance.
Pass caller as an argument and check if the caller is instanceof required class - multithreaded solution, cannot bypass by reflecion.
Get thread stack dump and check top entry - weird, heavy but possible
Create proxy - but that will be overheaded variation of solution 1.
You may be able to satisfy this requirement by using the class Class method getEnclosingMethod(). This is how it works (docs here):
If this Class object represents a local or anonymous class within a method, returns a Method object representing the immediately enclosing method of the underlying class.
The signature for methodA() should be changed to accept a Class object as parameter.
public void methodA(Class c) { }
The legal method from ClassB should create an anonymous class object, and pass its class as argument to methodA().
public void methodB() throws IllegalAccessException, NoSuchMethodException {
new ClassA().methodA(new Object(){}.getClass());
}
Then methodA() should check if the class enclosing method is indeed methodB() from ClassB.
public void methodA(Class c) throws IllegalAccessException, NoSuchMethodException {
if (c.getEnclosingMethod().equals(ClassB.class.getMethod("methodB"))) {
System.out.println("You are allowed to call");
} else {
throw new IllegalAccessException("You are not allowed to call");
}
}
Disadvantages:
You must instantiate a new object every time you call methodB(). This may get expensive depending on how many times you do it. Instead, you could create a local class inside methodB() so there is no object creation overhead:
public void methodB() throws IllegalAccessException, NoSuchMethodException {
class Local {};
new ClassA().methodA(Local.class);
}
You need to handle NoSuchMethodException and change the code if methodB() name changes;
Someone with access to the code could still modify methodB() to return the anonymous object class to another method, and use it to call methodA() from there. So this is not a perfect solution, but may be enough for your use case.

Categories

Resources