I really like the java's try-with-resources behavior. I'm wondering is it possible to use the same behavior for an already constructed resource? for instance if I have to call open() on some resources can I call it as part of the try-with-resource and still have it be auto-closed, or even just pass the resource after I open it to have it close.
I suspect the answer is no, but just wanted to make sure I know of any useful syntax.
If the open() method returns an object which implements AutoCloseable and it is legal to close the resource after open() is called, this will work. No magic here.
try (MyAutoCloseable resource = Foo.open()) {
// .. do your work
}
You can do this... All that matters is that your resources are declared in the statement; which means you can do something like this:
final Foo toBeOpened = ...;
toBeOpened.open();
try (
final Foo opened = toBeOpened;
) {
/* work with opened */
}
Related
I am trying to modularize my code but it involves passing around my object that implements AutoCloseable. Let say I have two public methods foo1 and foo2:
public class MyClass {
public void foo1() {
// Connection implements AutoCloseable
try (Connection conn = createConnection()) {
foo2(conn);
// is the connection closed or the behavior unpredictable?
conn.doSomethingElse();
}
}
public void foo2(Connection conn) {
try (conn) {
// do something with the Connection
}
}
}
I want to call foo2 from foo1, but also allow other classes to use foo2 separately.
public class OtherClass {
public void doSomething() {
MyClass myClass = new MyClass();
myClass.foo2(createConnection());
}
}
Does this lead to the connection being closed in foo1() after the call to foo2? Or should I put the try-with-resources in the calling methods (such as the doSomething() in OtherClass)?
Your foo1 method closes the connection after foo2 has used it. There is no need for foo2 to close the connection and it shouldn't. You're making it have an unexpected side-effect. E.g. when you call conn.doSomethingElse() inside foo1, you will find it won't work because the connection has been closed by the call to foo2. It's a violation of the principle of least astonishment because the method name does not reveal this side-effect.
If you called it foo2AndCloseTheConnection then you make clear what it does, but I recommend following the rule of thumb that the method that creates the closeable should be the only one to close it. If you follow this consistently, you'll never need to look inside a function to see whether or not something you've opened is closed by that function. You'll simply close it yourself explicitly.
If you want foo2 to be called from other methods, you need to make those methods close the connection:
public void doSomething() {
MyClass myClass = new MyClass();
try (Connection connection = createConnection()) {
myClass.foo2(connection);
}
}
Yes, foo2 closes the connection so it will be invalid when control returns to foo1. Nothing unpredictable about it.
It's a good rule to have things closed by the same code that creates them. But it would be good to be able to nest these things and let them share the same connection and transaction. One solution would be to have each of these data accessing methods receive the connection as a parameter and have an outer layer that gets the connection and makes sure it gets closed.
You're basically trying to reinvent Spring a bit at a time. Spring gives you the ability to have services that can use the same connection and lets you control how and whether transactions are propagated between them. This is done using AOP to wrap objects with around advice that gets the current connection for the thread from a threadlocal data structure. Much easier to use spring (or whatever container).
To be clear: I have an object which is continiously changing its values during the runtime and I want to save the created and modified object on a file.
I found how to that and I found also how to read back the object saving it into one another. But the question is: is it possible to call the class constructor of my object with the only parameter of the file in which the object I want to retrieve is stored?
NeuralNetwork(File fs){
ObjectInputStream ois;
changeFileSave(fs); //just sets the file as savefile for the future
try{
ois = new ObjectInputStream(new FileInputStream(_saveNet)); //_saveNet = fs
this = (NeuralNetwork) ois.readObject();
}
catch(Exception e){
//error message
}
}
It gives me an error on 'this ='
If it's possible how do I do something like this?
Thank you
The keyword this is a read-only reference, you can never write this = even in the constructor. Moreover, the constructor in java does not return anything.
You would have to take the object you've read and map its properties one by one (or using reflection) to the properties you have in the object you're instantiating.
However, I would submit that by passing a file to a constructor and doing the IO in it you are violating separation of concerns. By writing things this way, you have forever tied a neural network to a File, with a whole host of attendant issues, including (not limited to) the fact that you may be storing your values elsewhere at some point.
IMO you are better off using a factory pattern to build your object and making your NeuralNetwork object a plain object. Then the ambiguity disappears because your factory method can simply return (NeuralNetwork) ois.readObject();
this = (NeuralNetwork) ois.readObject();
Consider this as a hidden final argument that points to the instance that is executing the method. Its value cannot be changed. If you want to make a variable point to an instance, there's no problem with that, as long as you don't use this.
What you want to do is more appropriate for a factory or factory method than for a constructor. Use one of this patterns (or a static method if you want to keep it very simple) to create your instance from the file. Not sure if you need many instances of that class, but if you only need one, you should consider using a Singleton getInstance() method instead the previously mentioned.
You can't assign this, since it is readonly. this always points to the instance itself and is used throughout the life of the object to access its methods and attributes.
If you want to create an instance of your NeuralNetwork class by reading data from a file, you could use a factory method:
public class NeuralNetwork {
private NeuralNetwork() { // private constructor forces us to use the
} // factory method to create instances
public static NeuralNetwork loadFromFile(File fs) {
ObjectInputStream ois;
this.changeFileSave(fs); // just sets the file as savefile for the future
try {
ois = new ObjectInputStream(new FileInputStream(_saveNet));
return (NeuralNetwork) ois.readObject();
}
catch(IOException e){
throw UncheckedIOException(e);
}
}
// other methods and attributes
}
Then, wherever you use your NeuralNetwork class and need an instance, use:
NeuralNetwork network = NeuralNetwork.loadFromFile(someFs);
// use network instance and have fun with it here
Note 1: I've defined a private constructor to force everyone use the loadFromFile factory method to create an instance. This means that this class can only be created from within a static method of this class.
Note 2: I've also rethrown the exception with an unchecked exception. This is personal taste. I wouldn't just log the exception and go on. Instead, I would throw the exception so that the caller handles it properly, because it doesn't make any sense to go on if an instance of the class hasn't been created. If you don't want to rethrow the exception as an unchecked one, just don't catch the original IOException and add a throws IOException clause to your factory method. This would force the callers of loadFromFile to catch the IOException and handle it.
Im creating a simple DBHelper for my postgre DB using a JDBC driver.
Im wondering what are the best practices?
For example, are methods like initConnection() closeConnection() or any other, should be static one? Like:
void foo{
DBHelper.initConnection();
// do some logic, maybe:
// Data someData = DBHelper.getSomeData();
DBHelper.closeConnection();
}
Or maybe better if i will create a DBHelper object and call method for object. Like:
void foo2{
DBHelper dbhelper = new DBHelper();
dbhelper.initConnection();
// do some logic, maybe:
// Data someData = dbhelper.getSomeData();
dbhelper.closeConnection();
}
Is it matter at all?
Do i need always check if connection is open before i will try to retrive some data? What if it is close? And always try to close it in finally block?
EDIT:
in answer to #Kayaman comment:
So my foo method like this?
void foo3{
Connection conn = DBHelper.getConnection();
// do some logic, maybe:
// Statement statement = conn.createStatement();
// some stmt work
conn.close() //do i need check if stmt is closed before?
}
That will make my DBHelper class usefull only to getting connection. There will be no logic inside? (like GetInterestingRecords() or GetRecordsWithId(30) ?
Have you thought about defining the connection properties in the server config file (if it is a web app) and have the session opened for the whole application lifecycle?
Before implementing DBHelper you should check if some java libraries may satisfy your needs. If you take a look at this there are listed some libraries that seem to fit your problem.
If you decide to go on with your own custom implementation I suggest to make DBHelper a normal class with no static methods for managing the connections; the main reason is that with static methods you cannot manage multiple (i.e. connections to different databases) db connections at the same time. If you are using a java 7 implementation in your onw library you could also implement tha AutoClosable inferface in order to better manage the resource you library is managing.
So I have a try/finally block. I need to execute a number of methods in the finally block. However, each one of those methods can throw an exception. Is there a way to ensure that all these methods are called (or attempted) without nested finally blocks?
This is what I do right now, which is pretty ugly :
protected void verifyTable() throws IOException {
Configuration configuration = HBaseConfiguration.create();
HTable hTable = null;
try {
hTable = new HTable(configuration, segmentMatchTableName);
//...
//various business logic here
//...
} finally {
try {
try {
if(hTable!=null) {
hTable.close(); //This can throw an IOException
}
} finally {
try {
generalTableHelper.deleteTable(configuration, segmentMatchTableName); //This can throw an IOException
} finally {
try {
generalTableHelper.deleteTable(configuration, wordMatchTableName); //This can throw an IOException
} finally {
generalTableHelper.deleteTable(configuration, haplotypeTableName); //This can throw an IOException
}
}
}
} finally {
HConnectionManager.deleteConnection(configuration, true); //This can throw an IOException
}
}
}
Is there a more-elegant way to do this?
The standard (working) way to right resource management in Java (the principle applies to other languages as well) is:
Resource resource = acquire(resource);
try {
use(resource);
} finally {
resource.release();
}
Or using the shortcut (with an extra bit of cleverness) in the current version of Java SE:
try (Resource resource = acquire(resource)) {
use(resource);
}
(As Joe K points out, you may need to wrap the resource to make it confirm to the specific interface that the Java language depends upon.)
Two resources, and you just apply the idiom twice:
Resource resource = acquire(resource);
try {
SubResource sub = resource.acquire();
try {
use(sub);
} finally {
sub.release();
}
} finally {
resource.release();
}
And in Java SE 7:
try (
Resource resource = acquire(resource);
SubResource sub = resource.acquire()
) {
use(resource, sub);
}
The really great advantage of the new language feature is that resource handling was more often than not broken when written out.
You might have more complicated exception handling. For instance, you don't want to throw low-level exceptions such as IOException through to the application proper - you probably want to wrap in some subtype of RuntimeException. This can, with Java's typicaly verboseness, be factored out using the Execute Around idiom (see this excellent question). From Java SE 8, there will also be shorter syntax with randomly different semantics.
with(new ResourceSubAction() { public void use(Resource resource, SubResource sub) {
... use resource, sub ...
}});
If this is Java 7, you could consider using the new try-with-resources construct. You may need to create some basic AutoCloseable wrappers for deleting the tables.
In general, there's no way out of this. You need multiple finally blocks.
However, I don't want to comment on your specific code, whether or not that's an appropriate design. It certainly looks pretty odd.
There is no way I'm afraid. There was a similar pattern when closing io resources. Eg what do you do when closing a file throws an IOException? Usually you just had to ignore it. As this was a bit if an anti pattern they introduced the try-with syntax in Java 7. For your example though I think there is no other option. Perhaps put each finally into its own method to make it clearer
To call multiple methods from a finally block, you have to ensure that none of them throw -- which is a good idea anyway, because any exception thrown from a finally block will override the exception or return value thrown from the try/catch.
The most common use case is a file or database connection, in which case you write a "close quietly" method (or use one from an existing library, such as Jakarta Commons IO). If the things you need to clean up don't let you use a pre-existing method, you write your own (in your case, deleteTableQuietly()).
If you're using JDK-7, you can also use the "try with resource" construct.
You could create an abstract class Action with an execute method, and derive from that class one class for each method throwing exception which you want to call, calling this method from the execute method. Then you can create a list of Actions and loop over the elements of the list, calling their execute method in a try finally block, ignoring exceptions.
deleteTableSilently(table1);
deleteTableSilently(table2);
deleteTableSilently(table3);
deleteTableSilently()
try
deleteTable()
catch whatever
log.error();
Consider using the java.util.concurrent framework -- if you code each call as an individual Callable (named or anonymous), you could use ExecutorService.invokeAll.
I have a class that must have some static methods. Inside these static methods I need to call the method getClass() to make the following call:
public static void startMusic() {
URL songPath = getClass().getClassLoader().getResource("background.midi");
}
However Eclipse tells me:
Cannot make a static reference to the non-static method getClass()
from the type Object
What is the appropriate way to fix this compile time error?
The Answer
Just use TheClassName.class instead of getClass().
Declaring Loggers
Since this gets so much attention for a specific usecase--to provide an easy way to insert log declarations--I thought I'd add my thoughts on that. Log frameworks often expect the log to be constrained to a certain context, say a fully-qualified class name. So they are not copy-pastable without modification. Suggestions for paste-safe log declarations are provided in other answers, but they have downsides such as inflating bytecode or adding runtime introspection. I don't recommend these. Copy-paste is an editor concern, so an editor solution is most appropriate.
In IntelliJ, I recommend adding a Live Template:
Use "log" as the abbreviation
Use private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger($CLASS$.class); as the template text.
Click Edit Variables and add CLASS using the expression className()
Check the boxes to reformat and shorten FQ names.
Change the context to Java: declaration.
Now if you type log<tab> it'll automatically expand to
private static final Logger logger = LoggerFactory.getLogger(ClassName.class);
And automatically reformat and optimize the imports for you.
As for the code example in the question, the standard solution is to reference the class explicitly by its name, and it is even possible to do without getClassLoader() call:
class MyClass {
public static void startMusic() {
URL songPath = MyClass.class.getResource("background.midi");
}
}
This approach still has a back side that it is not very safe against copy/paste errors in case you need to replicate this code to a number of similar classes.
And as for the exact question in the headline, there is a trick posted in the adjacent thread:
Class currentClass = new Object() { }.getClass().getEnclosingClass();
It uses a nested anonymous Object subclass to get hold of the execution context. This trick has a benefit of being copy/paste safe...
Caution when using this in a Base Class that other classes inherit from:
It is also worth noting that if this snippet is shaped as a static method of some base class then currentClass value will always be a reference to that base class rather than to any subclass that may be using that method.
In Java7+ you can do this in static methods/fields:
MethodHandles.lookup().lookupClass()
I wrestled with this myself. A nice trick is to use use the current thread to get a ClassLoader when in a static context. This will work in a Hadoop MapReduce as well. Other methods work when running locally, but return a null InputStream when used in a MapReduce.
public static InputStream getResource(String resource) throws Exception {
ClassLoader cl = Thread.currentThread().getContextClassLoader();
InputStream is = cl.getResourceAsStream(resource);
return is;
}
Simply use a class literal, i.e. NameOfClass.class
Try it
Thread.currentThread().getStackTrace()[1].getClassName()
Or
Thread.currentThread().getStackTrace()[2].getClassName()
getClass() method is defined in Object class with the following signature:
public final Class getClass()
Since it is not defined as static, you can not call it within a static code block. See these answers for more information: Q1, Q2, Q3.
If you're in a static context, then you have to use the class literal expression to get the Class, so you basically have to do like:
Foo.class
This type of expression is called Class Literals and they are explained in Java Language Specification Book as follows:
A class literal is an expression consisting of the name of a class, interface, array, or primitive type followed by a `.' and the token class. The type of a class literal is Class. It evaluates to the Class object for the named type (or for void) as defined by the defining class loader of the class of the current instance.
You can also find information about this subject on API documentation for Class.
I had the same problem !
but to solve it just modify your code as following.
public static void startMusic() {
URL songPath = YouClassName.class.getClassLoader().getResource("background.midi");
}
this worked fine with me hope it will also work fine with you.
Suppose there is a Utility class, then sample code would be -
URL url = Utility.class.getClassLoader().getResource("customLocation/".concat("abc.txt"));
CustomLocation - if any folder structure within resources otherwise remove this string literal.
Try something like this. It works for me. Logg (Class name)
String level= "";
Properties prop = new Properties();
InputStream in =
Logg.class.getResourceAsStream("resources\\config");
if (in != null) {
prop.load(in);
} else {
throw new FileNotFoundException("property file '" + in + "' not found in the classpath");
}
level = prop.getProperty("Level");