Does Java have a using statement that can be used when opening a session in hibernate?
In C# it is something like:
using (var session = new Session())
{
}
So the object goes out of scope and closes automatically.
Java 7 introduced Automatic Resource Block Management which brings this feature to the Java platform. Prior versions of Java didn't have anything resembling using.
As an example, you can use any variable implementing java.lang.AutoCloseable in the following way:
try(ClassImplementingAutoCloseable obj = new ClassImplementingAutoCloseable())
{
...
}
Java's java.io.Closeable interface, implemented by streams, automagically extends AutoCloseable, so you can already use streams in a try block the same way you would use them in a C# using block. This is equivalent to C#'s using.
As of version 5.0, Hibernate Sessions implement AutoCloseable and can be auto-closed in ARM blocks. In previous versions of Hibernate Session did not implement AutoCloseable. So you'll need to be on Hibernate >= 5.0 in order to use this feature.
Before Java 7, there was no such feature in Java (for Java 7 and up see Asaph's answer regarding ARM).
You needed to do it manually and it was a pain:
AwesomeClass hooray = null;
try {
hooray = new AwesomeClass();
// Great code
} finally {
if (hooray!=null) {
hooray.close();
}
}
And that's just the code when neither // Great code nor hooray.close() can throw any exceptions.
If you really only want to limit the scope of a variable, then a simple code block does the job:
{
AwesomeClass hooray = new AwesomeClass();
// Great code
}
But that's probably not what you meant.
Since Java 7 it does: http://blogs.oracle.com/darcy/entry/project_coin_updated_arm_spec
The syntax for the code in the question would be:
try (Session session = new Session())
{
// do stuff
}
Note that Session needs to implement AutoClosable or one of its (many) sub-interfaces.
Technically:
DisposableObject d = null;
try {
d = new DisposableObject();
}
finally {
if (d != null) {
d.Dispose();
}
}
The closest java equivalent is
AwesomeClass hooray = new AwesomeClass();
try{
// Great code
} finally {
hooray.dispose(); // or .close(), etc.
}
As of now, no.
However there is a proposal of ARM for Java 7.
If you're interested in resource management, Project Lombok offers the #Cleanup annotation. Taken directly from their site:
You can use #Cleanup to ensure a given
resource is automatically cleaned up
before the code execution path exits
your current scope. You do this by
annotating any local variable
declaration with the #Cleanup
annotation like so:
#Cleanup InputStream in = new FileInputStream("some/file");
As a
result, at the end of the scope you're
in, in.close() is called. This call is
guaranteed to run by way of a
try/finally construct. Look at the
example below to see how this works.
If the type of object you'd like to
cleanup does not have a close()
method, but some other no-argument
method, you can specify the name of
this method like so:
#Cleanup("dispose") org.eclipse.swt.widgets.CoolBar bar = new CoolBar(parent, 0);
By default, the cleanup method is presumed to be
close(). A cleanup method that takes
argument cannot be called via
#Cleanup.
Vanilla Java
import java.io.*;
public class CleanupExample {
public static void main(String[] args) throws IOException {
InputStream in = new FileInputStream(args[0]);
try {
OutputStream out = new FileOutputStream(args[1]);
try {
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
} finally {
out.close();
}
} finally {
in.close();
}
}
}
With Lombok
import lombok.Cleanup;
import java.io.*;
public class CleanupExample {
public static void main(String[] args) throws IOException {
#Cleanup InputStream in = new FileInputStream(args[0]);
#Cleanup OutputStream out = new FileOutputStream(args[1]);
byte[] b = new byte[10000];
while (true) {
int r = in.read(b);
if (r == -1) break;
out.write(b, 0, r);
}
}
}
No, Java has no using statement equivalent.
In java 8 you can use try. Please refer to following page. http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html
Please see this List of Java Keywords.
The using keyword is unfortunately not part of the list.
And there is also no equivalence of the C# using keyword through any other keyword as for now in Java.
To imitate such "using" behaviour, you will have to use a try...catch...finally block, where you would dispose of the resources within finally.
ARM blocks, from project coin will be in Java 7. This is feature is intended to bring similar functionality to Java as the .Net using syntax.
To answer the question regarding limiting scope of a variable, instead of talking about automatically closing/disposing variables.
In Java you can define closed, anonymous scopes using curly brackets. It's extremely simple.
{
AwesomeClass hooray = new AwesomeClass()
// Great code
}
The variable hooray is only available in this scope, and not outside it.
This can be useful if you have repeating variables which are only temporary.
For example, each with index. Just like the item variable is closed over the for loop (i.e., is only available inside it), the index variable is closed over the anonymous scope.
// first loop
{
Integer index = -1;
for (Object item : things) {index += 1;
// ... item, index
}
}
// second loop
{
Integer index = -1;
for (Object item : stuff) {index += 1;
// ... item, index
}
}
I also use this sometimes if you don't have a for loop to provide variable scope, but you want to use generic variable names.
{
User user = new User();
user.setId(0);
user.setName("Andy Green");
user.setEmail("andygreen#gmail.com");
users.add(user);
}
{
User user = new User();
user.setId(1);
user.setName("Rachel Blue");
user.setEmail("rachelblue#gmail.com");
users.add(user);
}
Related
I have this input stream that checks if I have a certain CAD file open or not. I am doing this by using an input stream to run a tasklist command with the name I want to check. I currently have a boolean that returns true if the specific CAD file isn't open. If the CAD file is open, it returns false. However, I want it to be able to loop this until the CAD file is open because as of right now I have to keep running it in order for it to work. I also need to be able to check this boolean from a separate class. I have it in my main right now so i could test it. My code looks like this...
public class AutoCadCheck {
public static void main(String[] argv) throws Exception {
String notOpen = "INFO: No tasks are running which match the specified criteria";
StringBuilder textBuilder = new StringBuilder();
String command = "tasklist /fi \"windowtitle eq Autodesk AutoCAD 2017 - [123-4567.dwg]";
int i;
InputStream myStream = Runtime.getRuntime().exec(command).getInputStream();
while ((i = myStream.read()) != -1) {
textBuilder.append((char) i);
}
String output = textBuilder.toString();
boolean logical = output.contains(notOpen);
if (logical) {
System.out.println("DWG Not Open");
} else {
System.out.print(output);
}
myStream.close();
}
}
My other class is going to have an 'if statement' that checks whether my boolean "logical" is false, and if so, print something. I have tried every possible method I could think of, but I cannot get it to function the way I want it to. Every other thing I found involving looping an inputstream didn't really apply to my situation. So hopefully someone can help me out in achieving what I want to do.
I would start by moving everything out of main and into a different class. This will make retrieving values and calling specific functions easier. Then create an object of that class in main. Once that is done, I'd create a get method for the boolean variable. Now to focus on the loop. Once the object is created in main, create a conditional loop inside of main which calls the function you need until a different condition is met. This condition might be met once the file is open. After the condition is met, it exits to another loop that relies on another conditional, such as user input.
public class AutoCadCheck {
public static void main(String[] argv) throws Exception {
AutoCadFile file = new AutoCadFile();
//loop 1
//Some conditional so the program will
//continue to run after the file has been found.
// while(){
//loop 2
//check to see if the file is open or not
//while(logical){
//}
//}
}
}
Other class
import java.io.IOException;
import java.io.InputStream;
public class AutoCadFile {
private String notOpen;
private StringBuilder textBuilder;
private String command;
private int i;
private InputStream myStream;
private String output;
private boolean logical;
public AutoCadFile() {
notOpen = "INFO: No tasks are running which match the specified criteria";
textBuilder = new StringBuilder();
command = "tasklist /fi \"windowtitle eq Autodesk AutoCAD 2017 - [123-4567.dwg]";
output = textBuilder.toString();
logical = output.contains(notOpen);
try {
myStream = Runtime.getRuntime().exec(command).getInputStream();
} catch (IOException e) {
e.printStackTrace();
}
}
public void checkForFileOpen() {
try {
while ((i = myStream.read()) != -1) {
textBuilder.append((char) i);
}
if (logical) {
System.out.println("DWG Not Open");
} else {
System.out.print(output);
}
myStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public boolean getFileBoolean() {
return logical;
}
}
My other class is going to have an if statement that checks whether my boolean logical is false ...
Well, logical is a local variable within a method. So no code in another class is going to be able to see it.
There are two common approaches to this kind of thing:
Make the variable (i.e. logical) a field of the relevant class. (Preferably NOT a static field because that leads to other problems.)
Put your code into a method that returns the value you are assigning to logical as a result.
From a design perspective the second approach is preferable ... because it reduces coupling relative to the first. But if your application is tiny, that hardly matters.
I can see a couple of other significant problems with your code.
When you use exec(String), you are relying on the exec method to split the command string into a command name and arguments. Unfortunately, exec does not understand the (OS / shell / whatever specific) rules for quoting, etcetera in commands. So it will make a mess of your quoted string. You need to do the splitting yourself; i.e something like this:
String[] command = new String{} {
"tasklist",
"/fi",
"windowtitle eq Autodesk AutoCAD 2017 - [123-4567.dwg]"
};
Your code potentially leaks an input stream. You should use a "try with resource" to avoid that; e.g.
try (InputStream myStream = Runtime.getRuntime().exec(command).getInputStream()) {
// do stuff
} // the stream is closed automatically ... always
By the definition of AutoCloseable interface,
I must call close() for ALL instances.
i.e. I must write like this.
try(A a = new A()){
//do something
}
In java.sound.sampled.SourceDataLine interface,
or more commonly, in java.sound.sampled.Line interface,
is it required to call close() for ALL instances,
or I must call close() ONLY AFTER open() has called ?
If the official document explicitly states that I must close only when isOpened ,
I want to write like this.
but I couldn't find mention.
//can I write like this ?
SourceDataLine sdl;
try{
sdl = AudioSystem.getSourceDataLine(audioFormat);
sdl.open(audioFormat,bufferSize);
}catch(LineUnavailableException ex){
throw new RuntimeException(null,ex);
}
try(SourceDataLine sdlInTryWithResources = sdl){
//do something
}
Your actual question should be “does it harm to call close() when the data line has not been opened?” and the answer is “no”, so you can simply use
try(SourceDataLine sdl = AudioSystem.getSourceDataLine(audioFormat)) {
sdl.open(audioFormat, bufferSize);
// work with sdl
}
catch(LineUnavailableException ex) {
throw new RuntimeException(ex);
}
Note that javax.sound.sampled.Line has been deliberately changed in Java 7 to extend AutoCloseable, whose sole purpose is to allow the resource to be used within a try-with-resource statement.
It seems that you are overthinking things.
Just image try-with-resources would not exist and write down your code as you would have done prior Java 1.7.
For sure, you end up with something like:
Whatever somethingThatNeedsClosing = null;
try {
somethingThatNeedsClosing = ...
somethingThatNeedsClosing.whatever();
} catch (NoIdeaException e) {
error handling
} finally {
if (somethingThatNeedsClosing != null) {
somethingThatNeedsClosing.close()
}
}
Try-with-resources simply allows you to reduce this example accordingly.
In other words: try-with-resources allows you to define one (or more) resource(s) that will be used within the try block; and that will finally be closed. As in: each and any resource declared for try ... will be closed.
More specifically: don't think about other instances of your resource. Focus on the one that you are currently dealing with.
According to the business logic, the output of one of the method is used as an input to another. The logic has linear flow.
To emulate the behaviour, now there is a controller class which has everything.
It is very messy, too much loc and hard to modify. Also the exception handling is very complex. The individual method does some handling but the global exceptions bubble up and which involves a lot of try catch statements.
Does there exists a design pattern to address this problem?
Example Controller Class Code
try{
Logic1Inputs logic1_inputs = new Logic1Inputs( ...<some other params>... );
Logic1 l = new Logic1(logic1_inputs);
try{
Logic1Output l1Output = l.execute();
} catch( Logic1Exception l1Exception) {
// exception handling
}
Logic2Inputs logic2_inputs = new Logic2Inputs(l1Output);
Logic2 l2 = new Logic2(logic2_inputs);
try{
Logic2Output l2Output = l2.execute();
} catch( Logic2Exception l2Exception) {
// exception handling
}
Logic3Inputs logic3_inputs = new Logic3Inputs(l1Output, l2Output);
Logic3 l3 = new Logic3(logic2_inputs);
try{
Logic3Output l3Output = l3.execute();
} catch( Logic3Exception l3Exception) {
// exception handling
}
} catch(GlobalException globalEx){
// exception handling
}
I think this is called pipeline: http://en.wikipedia.org/wiki/Pipeline_%28software%29 This pattern is used for algorithms in which data flows through a sequence of tasks or stages.
You can search for a library that does this( http://code.google.com/p/pipelinepattern ) or try your own java implementation
Basically you have all you objects in a list and the output from one si passed to the next. This is a naive implementation but you can add generics and all you need
public class BasicPipelinePattern {
List<Filter> filters;
public Object process(Object input) {
for (Filter c : filters) {
try {
input = c.apply(input);
} catch (Exception e) {
// exception handling
}
}
return input;
}
}
public interface Filter {
public Object apply(Object o);
}
When faced with problems like this, I like to see how other programming languages might solve it. Then I might borrow that concept and apply it to the language that I'm using.
In javascript, there has been much talk of promises and how they can simplify not only asynchronous processing, but error handling. This page is a great introduction to the problem.
Then approach has been called using "thenables". Here's the pseudocode:
initialStep.execute().then(function(result1){
return step2(result1);
}).then(function(result2){
return step3(result3);
}).error(function(error){
handle(error);
}).done(function(result3){
handleResult(result3)
});
The advantage of this pattern is that you can focus on the processing and effectively handle errors in one place without needing to worry about checking for success at each step.
So how would this work in java? I would take a look at one of the promises/futures libraries, perhaps jdeferred. I would expect that you could put something like this together (assuming java 8 for brevity):
initialPromise.then( result1 -> {
Logic2 logic2 = new Logic2(new Logic2Inputs(result1));
return logic2.execute();
}).then(result2 -> {
Logic3 logic3 = new Logic3(new Logic3Inputs(result2));
return logic2.execute();
}).catch(exception -> {
handleException(exception)
}).finally( result -> {
handleResult(result);
});
This does, of course gloss over a hidden requirement in your code. You mention that in step 3 you need the output for both step 1 and step 2. If you were writing scala, there is syntactic sugar that would handle this for you (leaving out error handling for the moment):
for(result1 <- initialStep.execute();
Logic2 logic2 = new Logic2(Logic2Input(result1));
result2 <- logic2.execute();
Logic3 logic3 = new Logic3(Logic3Input(result1, result2));
result3 <- logic3.execute()) yield result3;
But since you don't have the ability here, then you are left to the choices of being refactoring each step to take only the output of the previous step, or nesting the processing so that result1 is still in scope when you need to set up step 3.
The classic alternative to this, as #user1121883 mentioned would be to use a Pipeline processor. The downside to this approach is that it works best if your input and output are the same type. Otherwise you are going to have to push Object around everywhere and do a lot of type checking.
Another alternative would be to expose a fluent interface for the pipeline. Again, you'd want to do some refactoring, perhaps to have a parameter-less constructor and a consistent interface for inputs and outputs:
Pipeline p = new Pipeline();
p.then(new Logic1())
.then(new Logic2())
.then(new Logic3())
.addErrorHandlder(e->handleError(e))
.complete();
This last option is more ideomatic java, but retains many of the advantages of the thenables processing, so it's probably the way that I would go.
I hope I didn't just find a bug in Java! I am running JDK 7u11 (mostly because that is the sanctioned JVM allowed by my employer) and I am noticing a very odd issue.
Namely, I am chunking data into a LinkedHashSet and writing it to a file using the ObjectOutputStream daisy changed through the GZIpOutputStream (mentioning this just in case it matters).
Now, when I get to the other side of the program and readObject() I notice that the size always reads 68, which I is the first size. The underlying table can have many more or less than 68, but the .size() method always returns 68. More troubling, when I try to manually iterate the underlying Set, it also stops at 68.
while(...) {
oos.writeInt(p_rid);
oos.writeObject(wptSet);
wptSet.clear();
// wptSet = new LinkedHashSet<>(); // **This somehow causes the heapsize to increase dramatically, but it does solve the problem**
}
And when reading it
Set<Coordinate> coordinates = (Set<Coordinate>) ois.readObject();
the coordinates.size() always returns 68. Now, I could make a workaround by also .writeInt() the size, but I can only iterate through 68 members!
Notice the wptSet = new LinkedHashSet<>() line actually solves the issue. The main problem with that is it makes my heapsize skyrocket when looking at the program in JVisualVM.
Update:
I actually just found a viable workaround that fixes the memory leak of re-instantiating wptSet... System.gc() Calling that after each call to .clear() actually keeps the memory leak away.
Either way, I shouldn't have to do this and shipping out the LinkedHashSet should not exhibit this behavior.
Alright, I think I understand what you are asking.
Here is an example to reproduce...
import java.util.*;
import java.io.*;
class Example {
public static void main(String[] args) throws Exception {
Set<Object> theSet = new LinkedHashSet<>();
final int size = 3;
for(int i = 0; i < size; ++i) {
theSet.add(i);
}
ByteArrayOutputStream bytesOut = new ByteArrayOutputStream();
ObjectOutputStream objectsOut = new ObjectOutputStream(bytesOut);
for(int i = 0; i < size; ++i) {
objectsOut.writeObject(theSet);
theSet.remove(i); // mutate theSet for each write
}
ObjectInputStream objectsIn = new ObjectInputStream(
new ByteArrayInputStream(bytesOut.toByteArray()));
for(;;) {
try {
System.out.println(((Set<?>)objectsIn.readObject()).size());
} catch(EOFException e) {
break;
}
}
}
}
The output is
3
3
3
What is going on here is that ObjectOutputStream detects that you are writing the same object every time. Each time theSet is written, a "shared reference" to the object is written so that the same object is deserialized each time. This is explained in the documentation:
Multiple references to a single object are encoded using a reference sharing mechanism so that graphs of objects can be restored to the same shape as when the original was written.
In this case you should use writeUnshared(Object) which will bypass this mechanism, instead of writeObject(Object).
I am trying to edit a class file and make it available to the JVM at runtime.
Is that possible, how can I do it?
For example:
main() {
for (int i=0;i<10;i++) {
NewClass.method();
//ask user if to continue..
}
}
public class NewClass() {
static void method() {
sysout("hi");
}
}
When this loop is executing, I want to change the file NewClass() and load it in the JVM, so that it prints "bye".
Here is the complete code:
try {
for (int iCount = 0; iCount < 10; iCount++) {
BufferedReader br = new BufferedReader(new InputStreamReader(
System.in));
System.out.print("Enter which method:");
int i = Integer.parseInt(br.readLine());
System.out.println(i);
if (i == 1) {
Called.calledMethod1();
} else {
Called.calledMethod2();
}
}
} catch (NumberFormatException nfe) {
System.err.println("Invalid Format!");
}
I want to run the main method of one class, and while it is running I want to refer to another class, edit it, and refer the 2nd class's same method and get different output.
I don't want to:
stop the jvm
edit the code
run the code again.
I want to
edit the code at run time, and get the changes reflected immediately.
You have to use Java reflection. Using reflection,
you load dynamically a class at runtime using Class forName method.
Using invoke method on the instance of Class you got,you can call any static method you want giving it's name.
If your class is fixed at design time, you just skeep the first point. Some code:
...
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter which class:");
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
className=br.readLine()
int results = compiler.run(null, null, null, className+".java");
if(results == 0){
Class clazz = Class.forName(className+".class");
System.out.print("Compiled successfully.Enter which method:");
Object returnValue=clazz.getMethod(br.readLine()).invoke(null);
}
...
But beware of security issues: the code above let anyone to execute each static method of each class accessible at runtime. If security is one of your concern, it's better if you first validate the input received from console and test that they match one of the class methods you whant to make available via console.
EDIT:
I better understand your question after I read your comment. In order to compile a class at runtime if you are targeting Java 6, you could use Java Compiler object. I have edit the code to include JavaCompiler usage.