Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #38859 > unrolled thread
| Started by | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| First post | 2019-04-04 05:22 -0700 |
| Last post | 2019-04-04 15:15 +0000 |
| Articles | 16 — 7 participants |
Back to article view | Back to comp.lang.java.programmer
Does this make sense? Eric Douglas <e.d.programmer@gmail.com> - 2019-04-04 05:22 -0700
Re: Does this make sense? Eric Sosman <esosman@comcast-dot-net.invalid> - 2019-04-04 09:03 -0400
Re: Does this make sense? Eric Douglas <e.d.programmer@gmail.com> - 2019-04-04 07:02 -0700
Re: Does this make sense? Eric Sosman <esosman@comcast-dot-net.invalid> - 2019-04-04 11:01 -0400
Re: Does this make sense? Eric Douglas <e.d.programmer@gmail.com> - 2019-04-04 08:21 -0700
Re: Does this make sense? Eric Douglas <e.d.programmer@gmail.com> - 2019-04-04 11:45 -0700
Re: Does this make sense? Arne Vajhøj <arne@vajhoej.dk> - 2019-04-04 20:33 -0400
Re: Does this make sense? Eric Douglas <e.d.programmer@gmail.com> - 2019-04-05 08:39 -0700
Re: Does this make sense? Arne Vajhøj <arne@vajhoej.dk> - 2019-04-05 12:31 -0400
Re: Does this make sense? bursejan@gmail.com - 2019-04-05 10:53 -0700
Re: Does this make sense? bursejan@gmail.com - 2019-04-05 10:57 -0700
Re: Does this make sense? bursejan@gmail.com - 2019-04-05 11:02 -0700
Re: Does this make sense? bursejan@gmail.com - 2019-04-05 11:13 -0700
Re: Does this make sense? Patrick Roemer <sangamon@netcologne.de> - 2019-04-05 17:43 +0200
Re: Does this make sense? Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> - 2019-04-07 22:14 +0200
Re: Does this make sense? Andreas Leitgeb <avl@logic.at> - 2019-04-04 15:15 +0000
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2019-04-04 05:22 -0700 |
| Subject | Does this make sense? |
| Message-ID | <f9818c55-5eb6-47f8-8ec9-d512861ddee7@googlegroups.com> |
Trying to avoid Eclipse compile warnings I end up with code like this.
FileOutputStream fos = null;
try {
fos = new FileOutputStream(myFile);
fos.write(myByteArray);
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
[toc] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2019-04-04 09:03 -0400 |
| Message-ID | <q84vam$lri$1@dont-email.me> |
| In reply to | #38859 |
On 4/4/2019 8:22 AM, Eric Douglas wrote:
> Trying to avoid Eclipse compile warnings I end up with code like this.
>
> FileOutputStream fos = null;
> try {
> fos = new FileOutputStream(myFile);
> fos.write(myByteArray);
> } catch (IOException e) {
> e.printStackTrace();
> } finally {
> try {
> fos.close();
Aside: I think you need a null-test here.
> } catch (IOException e) {
> e.printStackTrace();
> }
> }
Consider try-with-resources:
try (FileOutputStream fos = new FileOutputStream(myFile)) {
fos.write(myByteArray);
} catch (IOException e) {
e.printStackTrace(); // a stopgap, at best
}
It's not quite equivalent (see "suppressed exception"), but it's
pretty close.
--
esosman@comcast-dot-net.invalid
Six hundred fifty-seven days to go.
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2019-04-04 07:02 -0700 |
| Message-ID | <c001151d-044c-4d1b-ad88-0efd923e4433@googlegroups.com> |
| In reply to | #38861 |
On Thursday, April 4, 2019 at 9:03:28 AM UTC-4, Eric Sosman wrote:
> > } finally {
> > try {
> > fos.close();
>
> Aside: I think you need a null-test here.
>
Is a null even possible? It would have to crash in the 'new'. I have Eclipse warning setup for "Null pointer access" is set to warn. I set one for "Potential null pointer access" and it does flag it. I normally have that one set to ignore. I wonder if that's just an unnecessary can of worms.
> > } catch (IOException e) {
> > e.printStackTrace();
> > }
> > }
>
> Consider try-with-resources:
>
> try (FileOutputStream fos = new FileOutputStream(myFile)) {
> fos.write(myByteArray);
> } catch (IOException e) {
> e.printStackTrace(); // a stopgap, at best
> }
>
> It's not quite equivalent (see "suppressed exception"), but it's
> pretty close.
>
Ah right, resources doesn't always work because in some cases I'm using Closeable objects instead of Autocloseable, and in some cases I'm creating the the object (in the case the java.io.File) in the same try block as the object (java.io.FileOutputStream) needing to be closed so they can't be created up front, but in this simple block that does look better.
try (FileOutputStream fos = new FileOutputStream(myFile)) {
fos.write(myByteArray);
} catch (IOException e) {
e.printStackTrace();
}
I initially just had a try block around the {new, write, close} and Eclipse complained it may not hit the close, because the write is throwing the IOException, so I moved that to a finally and it got ugly.
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2019-04-04 11:01 -0400 |
| Message-ID | <q85699$oq6$1@dont-email.me> |
| In reply to | #38863 |
On 4/4/2019 10:02 AM, Eric Douglas wrote:
> On Thursday, April 4, 2019 at 9:03:28 AM UTC-4, Eric Sosman wrote:
>>> } finally {
>>> try {
>>> fos.close();
>>
>> Aside: I think you need a null-test here.
>>
> Is a null even possible? It would have to crash in the 'new'. [...]
Exactly.
>> Consider try-with-resources: [...]
>
> Ah right, resources doesn't always work because in some cases I'm using Closeable objects instead of Autocloseable, and in some cases I'm creating the the object (in the case the java.io.File) in the same try block as the object (java.io.FileOutputStream) needing to be closed so they can't be created up front, but in this simple block that does look better.
I foolishly assumed that your example code resembled the problem
you actually have. I should have known better; sorry.
--
esosman@comcast-dot-net.invalid
Six hundred fifty-seven days to go.
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2019-04-04 08:21 -0700 |
| Message-ID | <c4b7026a-08ad-4c11-99cd-b1546e5c42ed@googlegroups.com> |
| In reply to | #38865 |
On Thursday, April 4, 2019 at 11:02:14 AM UTC-4, Eric Sosman wrote: > > I foolishly assumed that your example code resembled the problem > you actually have. I should have known better; sorry. Oh that was the problem in this class, the try-with-resources does work and makes it look cleaner. I'm just saying I have other classes with a similar situation where it cannot be used. I can work up some sample code demonstrating in a bit.
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2019-04-04 11:45 -0700 |
| Message-ID | <b8961ec3-eac5-45da-aa5d-11144bcae219@googlegroups.com> |
| In reply to | #38865 |
On Thursday, April 4, 2019 at 11:02:14 AM UTC-4, Eric Sosman wrote:
> > Ah right, resources doesn't always work because in some cases I'm using Closeable objects instead of Autocloseable, and in some cases I'm creating the the object (in the case the java.io.File) in the same try block as the object (java.io.FileOutputStream) needing to be closed so they can't be created up front, but in this simple block that does look better.
>
> I foolishly assumed that your example code resembled the problem
> you actually have. I should have known better; sorry.
>
So for example an Autocloseable can't be used in try-with-resources because it has 2 places to instantiate. I keep messing with code like the following which keeps giving different errors on what may not be closed.
public static String testMethod(final String db_connect_string, final String db_userid, final String db_password, final String dbDriver, final String queryText) throws ClassNotFoundException {
Class.forName(dbDriver);
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
conn = DriverManager.getConnection(db_connect_string, db_userid, db_password);
ps = conn.prepareStatement(queryText, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = ps.getResultSet();
} catch (final SQLException e) {
e.printStackTrace();
try {
if (ps != null) {
ps.close();
}
if (conn != null) {
conn.close();
}
conn = DriverManager.getConnection("alternate connect string", db_userid, db_password);
ps = conn.prepareStatement(queryText, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = ps.getResultSet();
} catch (final SQLException e1) {
e1.printStackTrace();
}
}
try {
while (rs.next()) {
System.out.println(rs.getRow());
}
} catch (final SQLException e1) {
e1.printStackTrace();
} finally {
try {
rs.close();
} catch (final SQLException e) {
e.printStackTrace();
throw new Error("SQL issue");
}
}
if (ps != null) {
try {
ps.close();
} catch (final SQLException e) {
e.printStackTrace();
if (conn != null) {
try {
conn.close();
} catch (final SQLException e1) {
e1.printStackTrace();
throw new Error("SQL issue");
}
}
throw new Error("SQL issue");
}
}
if (conn != null) {
try {
conn.close();
} catch (final SQLException e) {
e.printStackTrace();
throw new Error("SQL issue");
}
}
return null;
}
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2019-04-04 20:33 -0400 |
| Message-ID | <q867p2$gv3$1@gioia.aioe.org> |
| In reply to | #38868 |
On 4/4/2019 2:45 PM, Eric Douglas wrote:
> So for example an Autocloseable can't be used in try-with-resources because it has 2 places to instantiate.
> I keep messing with code like the following which keeps giving different errors on what may not be closed.
>
> public static String testMethod(final String db_connect_string, final String db_userid, final String db_password, final String dbDriver, final String queryText) throws ClassNotFoundException {
> Class.forName(dbDriver);
> Connection conn = null;
> PreparedStatement ps = null;
> ResultSet rs = null;
> try {
> conn = DriverManager.getConnection(db_connect_string, db_userid, db_password);
> ps = conn.prepareStatement(queryText, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
> rs = ps.getResultSet();
> } catch (final SQLException e) {
> e.printStackTrace();
> try {
> if (ps != null) {
> ps.close();
> }
> if (conn != null) {
> conn.close();
> }
> conn = DriverManager.getConnection("alternate connect string", db_userid, db_password);
> ps = conn.prepareStatement(queryText, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
> rs = ps.getResultSet();
> } catch (final SQLException e1) {
> e1.printStackTrace();
> }
> }
> try {
> while (rs.next()) {
> System.out.println(rs.getRow());
> }
> } catch (final SQLException e1) {
> e1.printStackTrace();
> } finally {
> try {
> rs.close();
> } catch (final SQLException e) {
> e.printStackTrace();
> throw new Error("SQL issue");
> }
> }
> if (ps != null) {
> try {
> ps.close();
> } catch (final SQLException e) {
> e.printStackTrace();
> if (conn != null) {
> try {
> conn.close();
> } catch (final SQLException e1) {
> e1.printStackTrace();
> throw new Error("SQL issue");
> }
> }
> throw new Error("SQL issue");
> }
> }
> if (conn != null) {
> try {
> conn.close();
> } catch (final SQLException e) {
> e.printStackTrace();
> throw new Error("SQL issue");
> }
> }
> return null;
> }
I would not duplicate functionality like that.
And I think it can be done without and still use resource try.
For inspiration:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
public class MultiTry {
public static String test(List<String> constr, String un, String pw) {
try(Connection con = DriverManager.getConnection(constr.get(0),
un, pw)) {
// do something with connection
return constr.get(0) + " worked";
} catch (SQLException e) {
if(constr.size() > 1) {
return test(constr.subList(1, constr.size()) , un, pw);
} else {
return "Houston we got a problem";
}
}
}
public static void main(String[] args) {
String res =
test(Arrays.asList("jdbc:mysql://localhost:3308/Test",
"jdbc:mysql://localhost:3307/Test", "jdbc:mysql://localhost:3306/Test"),
"root", "");
System.out.println(res);
}
}
Arne
PS: Class.forName for JDBC driver has not been necessary since Java 1.6
from 2006 (13 years ago).
[toc] | [prev] | [next] | [standalone]
| From | Eric Douglas <e.d.programmer@gmail.com> |
|---|---|
| Date | 2019-04-05 08:39 -0700 |
| Message-ID | <636ed842-3212-4955-8c81-0a48f162b6b9@googlegroups.com> |
| In reply to | #38871 |
On Thursday, April 4, 2019 at 8:33:50 PM UTC-4, Arne Vajhøj wrote:
> return test(constr.subList(1, constr.size()) , un, pw);
> } else {
> return "Houston we got a problem";
> }
Interesting solution, I would not have thought to use recursion for that but it works.
I have another related sample, I came up with a self-contained runnable class.
This one is a bit long, but pasting it inline anyhow as this forum doesn't appear to accept attachments. Where does it expect to close the FileWriter?
import static java.nio.file.StandardWatchEventKinds.ENTRY_CREATE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_DELETE;
import static java.nio.file.StandardWatchEventKinds.ENTRY_MODIFY;
import static java.nio.file.StandardWatchEventKinds.OVERFLOW;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.WatchEvent;
import java.nio.file.WatchEvent.Kind;
import java.nio.file.WatchKey;
import java.nio.file.WatchService;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
public class TestFileWatch {
static WatchService watcher = null;
static boolean listenEvents = false;
public static void main(final String[] args) {
final File output = new File("c:\\test\\filecountlog.txt");
try {
output.createNewFile();
final FileWriter fwr = new FileWriter(output);
final Map<WatchKey, Path> keys = new HashMap<>();
/**
* Process all events for keys queued to the watcher
*/
final Thread listenThread = new Thread(() -> {
System.out.println("watch initiated");
for (;;) {
// wait for key to be signaled
WatchKey key;
try {
key = watcher.take();
} catch (final InterruptedException x) {
try {
watcher.close();
watcher = null;
System.out.println("watcher terminated");
} catch (final IOException e) {
e.printStackTrace();
}
return;
}
final Path dir = keys.get(key);
if (dir == null) {
System.err.println("WatchKey not recognized!!");
continue;
}
for (final WatchEvent<?> event : key.pollEvents()) {
final Kind<?> kind = event.kind();
// TBD - provide example of how OVERFLOW event is handled
if (kind == OVERFLOW) {
continue;
}
// Context for directory entry event is the file name of entry
final WatchEvent<Path> ev = (WatchEvent<Path>) (event);
final Path name = ev.context();
final Path child = dir.resolve(name);
// print out event
if (listenEvents) {
if (kind == ENTRY_CREATE) {
try {
fwr.write(getTimeStamp() + " " + child + " Created" + System.getProperty("line.separator"));
fwr.write(getTimeStamp() + " Now contains "
+ child.getParent().toFile().listFiles().length + System.getProperty("line.separator"));
fwr.flush();
} catch (final IOException e) {
e.printStackTrace();
}
} else {
if (kind == ENTRY_MODIFY) {
// does not affect the count
} else {
if (kind == ENTRY_DELETE) {
try {
fwr.write(getTimeStamp() + " " + child + " Deleted" + System.getProperty("line.separator"));
fwr.write(getTimeStamp() + " Now contains "
+ child.getParent().toFile().listFiles().length + System.getProperty("line.separator"));
fwr.flush();
} catch (final IOException e) {
e.printStackTrace();
}
} else {
System.out.println("Unknown event type : " + kind + " encountered");
}
}
}
}
// reset key and remove from set if directory no longer accessible
final boolean valid = key.reset();
if (!valid) {
keys.remove(key);
// all directories are inaccessible
if (keys.isEmpty()) {
break;
}
}
}
}
});
EventQueue.invokeLater(() -> {
try {
watcher = FileSystems.getDefault().newWatchService();
final Path p = Paths.get("c:\\temp\\");
keys.put(p.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY), p);
final JButton startMe = new JButton("Start Me");
final JButton stopMe = new JButton("Stop Me");
int w = 320;
int h = 100;
// check for dispose or close, not both? (which one?)
final JFrame fwWin = new JFrame() {
@Override
public void dispose() {
super.dispose();
try {
System.out.println("window disposed");
fwr.close();
listenThread.interrupt();
} catch (final IOException e) {
e.printStackTrace();
}
}
};
fwWin.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(final WindowEvent e) {
try {
System.out.println("window closed");
fwr.close();
listenThread.interrupt();
} catch (final IOException e1) {
e1.printStackTrace();
}
}
});
fwWin.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
fwWin.setSize(w, h);
fwWin.setTitle("TEMP File Watcher");
fwWin.setLayout(new GridLayout(1, 2));
final Insets i = fwWin.getInsets();
w = w - i.left - i.right;
h = h - i.top - i.bottom;
fwWin.add(startMe);
fwWin.add(stopMe);
startMe.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent ev) {
startMe.setEnabled(false);
listenEvents = true;
try {
fwr.write(getTimeStamp() + " started listening for changes" + System.getProperty("line.separator"));
fwr.flush();
} catch (final IOException e) {
e.printStackTrace();
}
stopMe.setEnabled(true);
}
});
stopMe.addActionListener(new ActionListener() {
@Override
public void actionPerformed(final ActionEvent ev) {
stopMe.setEnabled(false);
listenEvents = false;
try {
fwr.write(getTimeStamp() + " stopped listening for changes" + System.getProperty("line.separator"));
fwr.flush();
} catch (final IOException e) {
e.printStackTrace();
}
startMe.setEnabled(true);
}
});
stopMe.setEnabled(false);
fwWin.setVisible(true);
listenThread.setDaemon(true);
listenThread.start();
} catch (final IOException e) {
e.printStackTrace();
}
});
} catch (final IOException e2) {
e2.printStackTrace();
}
}
public static String getTimeStamp() {
final StringBuilder sb = new StringBuilder();
final Calendar now = Calendar.getInstance();
final DecimalFormat f2 = new DecimalFormat("00");
final DecimalFormat f3 = new DecimalFormat("000");
final DecimalFormat f4 = new DecimalFormat("0000");
sb.append(f4.format(now.get(Calendar.YEAR)));
sb.append("-");
sb.append(f2.format(now.get(Calendar.MONTH) + 1));
sb.append("-");
sb.append(f2.format(now.get(Calendar.DATE)));
sb.append(" ");
sb.append(f2.format(now.get(Calendar.HOUR_OF_DAY)));
sb.append(":");
sb.append(f2.format(now.get(Calendar.MINUTE)));
sb.append(":");
sb.append(f2.format(now.get(Calendar.SECOND)));
sb.append(".");
sb.append(f3.format(now.get(Calendar.MILLISECOND)));
return sb.toString();
}
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2019-04-05 12:31 -0400 |
| Message-ID | <q87vu2$7tv$1@gioia.aioe.org> |
| In reply to | #38872 |
On 4/5/2019 11:39 AM, Eric Douglas wrote:
> On Thursday, April 4, 2019 at 8:33:50 PM UTC-4, Arne Vajhøj wrote:
>> return test(constr.subList(1, constr.size()) , un, pw);
>> } else {
>> return "Houston we got a problem";
>> }
>
> Interesting solution, I would not have thought to use recursion for that but it works.
You could also use a loop.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
public class MultiTry {
public static String test(List<String> constr, String un, String pw) {
for(String constr1 : constr) {
try(Connection con = DriverManager.getConnection(constr1,
un, pw)) {
// do something with connection
return constr1 + " worked";
} catch (SQLException e) {
// nothing => go next connection string
}
}
return "Houston we got a problem";
}
public static void main(String[] args) {
String res =
test(Arrays.asList("jdbc:mysql://localhost:3308/Test",
"jdbc:mysql://localhost:3307/Test", "jdbc:mysql://localhost:3306/Test"),
"root", "");
System.out.println(res);
}
}
Arne
[toc] | [prev] | [next] | [standalone]
| From | bursejan@gmail.com |
|---|---|
| Date | 2019-04-05 10:53 -0700 |
| Message-ID | <d3b02831-ee3f-4b78-a446-ecccb3d0115f@googlegroups.com> |
| In reply to | #38872 |
I think you don't need an extra thread. Since Swing runs anyway in its own thread. If you display a non-modal window, the current thread will not block. And you can perform the for(;;) loop in the main thread itself, without starting a thread. The problem is only, how does the main thread get events from the watcher and from the window? Well the same way, via interrupt(). So the main thread can detect whether it go a watcher.take() or whether it got interrupted. And it can gracefully terminate and close also whatever resources it has opened. If some tooling shows an error somewhere, submit a bug report. Lets see what they say... On Friday, April 5, 2019 at 5:39:25 PM UTC+2, Eric Douglas wrote: > On Thursday, April 4, 2019 at 8:33:50 PM UTC-4, Arne Vajhøj wrote:
[toc] | [prev] | [next] | [standalone]
| From | bursejan@gmail.com |
|---|---|
| Date | 2019-04-05 10:57 -0700 |
| Message-ID | <4ce08746-597b-4aab-a53d-13aa3723b083@googlegroups.com> |
| In reply to | #38875 |
Instead of interrupt(), you might also simply close the WatchService. It should cancel WatchKeys that are in progress. https://docs.oracle.com/javase/7/docs/api/java/nio/file/WatchKey.html Disclaimer: I have never used watchers. I guess some IDEs use it also, to get notified about changed stuff. So its quite useful... On Friday, April 5, 2019 at 7:53:44 PM UTC+2, burs...@gmail.com wrote: > I think you don't need an extra thread. Since > Swing runs anyway in its own thread. > If you display a non-modal window, the current > thread will not block. And you can perform > > the for(;;) loop in the main thread itself, without > starting a thread. The problem is only, how does > the main thread get events from the watcher and > from the window? Well the same way, via interrupt(). > > So the main thread can detect whether it go a > watcher.take() or whether it got interrupted. > And it can gracefully terminate and close also > whatever resources it has opened. If some tooling > > shows an error somewhere, submit a bug report. > Lets see what they say... > > On Friday, April 5, 2019 at 5:39:25 PM UTC+2, Eric Douglas wrote: > > On Thursday, April 4, 2019 at 8:33:50 PM UTC-4, Arne Vajhøj wrote:
[toc] | [prev] | [next] | [standalone]
| From | bursejan@gmail.com |
|---|---|
| Date | 2019-04-05 11:02 -0700 |
| Message-ID | <4ffe145e-d766-46ad-9c6e-e794450a195c@googlegroups.com> |
| In reply to | #38876 |
Actually I don't know exactly what IDEs do, like for example IntelliJ. They could also follow other strategies, like react on active/deactive of window, or react on terminate of a ant job or build job, etc.. Sometimes, if there are too many changes, I already notices that some of them might not be recognized. I also don't know whether a watcher can report content change. Ok I see OVERFLOW, events may have been lost, and ENTRY_MODIFY(*), entry in the directory has been modified. Oki Doki, everything is there, but because of OVERLOW(*) I guess a tool needs a fallback strategy. Thanks, interesting! (*) https://docs.oracle.com/javase/7/docs/api/java/nio/file/StandardWatchEventKinds.html On Friday, April 5, 2019 at 7:57:13 PM UTC+2, burs...@gmail.com wrote: > Instead of interrupt(), you might also > simply close the WatchService. It should cancel > WatchKeys that are in progress. > > https://docs.oracle.com/javase/7/docs/api/java/nio/file/WatchKey.html > > Disclaimer: I have never used watchers. I > guess some IDEs use it also, to get notified > about changed stuff. So its quite useful... > > On Friday, April 5, 2019 at 7:53:44 PM UTC+2, burs...@gmail.com wrote: > > I think you don't need an extra thread. Since > > Swing runs anyway in its own thread. > > If you display a non-modal window, the current > > thread will not block. And you can perform > > > > the for(;;) loop in the main thread itself, without > > starting a thread. The problem is only, how does > > the main thread get events from the watcher and > > from the window? Well the same way, via interrupt(). > > > > So the main thread can detect whether it go a > > watcher.take() or whether it got interrupted. > > And it can gracefully terminate and close also > > whatever resources it has opened. If some tooling > > > > shows an error somewhere, submit a bug report. > > Lets see what they say... > > > > On Friday, April 5, 2019 at 5:39:25 PM UTC+2, Eric Douglas wrote: > > > On Thursday, April 4, 2019 at 8:33:50 PM UTC-4, Arne Vajhøj wrote:
[toc] | [prev] | [next] | [standalone]
| From | bursejan@gmail.com |
|---|---|
| Date | 2019-04-05 11:13 -0700 |
| Message-ID | <2308a448-c264-421f-bea5-557c84ae9be0@googlegroups.com> |
| In reply to | #38877 |
BTW: A close() would be also a needed option for
java.net.Socket access that is in progress, since
they don't react on interrupt(). Only some java.nio
can do it. But they just hook into the interrupt()
and install a closer... Simple check out where
this package private method of Thread is used:
void blockedOn(Interruptible b)
I don't know whether a WatchService also installs such
a closer while in progress. blockOn is accessed indirectly
via SharedSecrets.getJavaLangAccess in the class
AbstractInterruptibleChannel. But since the interface
of WatcherService says, WatchKey take() throws
InterruptedException, I guess interrupt() is nevertheless
supported by a WatcherService...
On Friday, April 5, 2019 at 8:03:05 PM UTC+2, burs...@gmail.com wrote:
> Actually I don't know exactly what IDEs do,
> like for example IntelliJ. They could also follow
> other strategies, like react on active/deactive
>
> of window, or react on terminate of a ant job
> or build job, etc.. Sometimes, if there are
> too many changes, I already notices that
>
> some of them might not be recognized. I also
> don't know whether a watcher can report content
> change. Ok I see OVERFLOW, events may have been
>
> lost, and ENTRY_MODIFY(*), entry in the directory has
> been modified. Oki Doki, everything is there,
> but because of OVERLOW(*) I guess a tool needs
>
> a fallback strategy.
>
> Thanks, interesting!
>
> (*)
> https://docs.oracle.com/javase/7/docs/api/java/nio/file/StandardWatchEventKinds.html
>
> On Friday, April 5, 2019 at 7:57:13 PM UTC+2, burs...@gmail.com wrote:
> > Instead of interrupt(), you might also
> > simply close the WatchService. It should cancel
> > WatchKeys that are in progress.
> >
> > https://docs.oracle.com/javase/7/docs/api/java/nio/file/WatchKey.html
> >
> > Disclaimer: I have never used watchers. I
> > guess some IDEs use it also, to get notified
> > about changed stuff. So its quite useful...
> >
> > On Friday, April 5, 2019 at 7:53:44 PM UTC+2, burs...@gmail.com wrote:
> > > I think you don't need an extra thread. Since
> > > Swing runs anyway in its own thread.
> > > If you display a non-modal window, the current
> > > thread will not block. And you can perform
> > >
> > > the for(;;) loop in the main thread itself, without
> > > starting a thread. The problem is only, how does
> > > the main thread get events from the watcher and
> > > from the window? Well the same way, via interrupt().
> > >
> > > So the main thread can detect whether it go a
> > > watcher.take() or whether it got interrupted.
> > > And it can gracefully terminate and close also
> > > whatever resources it has opened. If some tooling
> > >
> > > shows an error somewhere, submit a bug report.
> > > Lets see what they say...
> > >
> > > On Friday, April 5, 2019 at 5:39:25 PM UTC+2, Eric Douglas wrote:
> > > > On Thursday, April 4, 2019 at 8:33:50 PM UTC-4, Arne Vajhøj wrote:
[toc] | [prev] | [next] | [standalone]
| From | Patrick Roemer <sangamon@netcologne.de> |
|---|---|
| Date | 2019-04-05 17:43 +0200 |
| Message-ID | <q87t34$l7l$1@newsreader4.netcologne.de> |
| In reply to | #38868 |
Responding to Eric Douglas:
> public static String testMethod(final String db_connect_string, final String db_userid, final String db_password, final String dbDriver, final String queryText) throws ClassNotFoundException {
> Class.forName(dbDriver);
> Connection conn = null;
> PreparedStatement ps = null;
> ResultSet rs = null;
> try {
> conn = DriverManager.getConnection(db_connect_string, db_userid, db_password);
> ps = conn.prepareStatement(queryText, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
> rs = ps.getResultSet();
> } catch (final SQLException e) {
> e.printStackTrace();
> try {
> if (ps != null) {
> ps.close();
> }
> if (conn != null) {
> conn.close();
> }
> conn = DriverManager.getConnection("alternate connect string", db_userid, db_password);
> ps = conn.prepareStatement(queryText, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
> rs = ps.getResultSet();
> } catch (final SQLException e1) {
> e1.printStackTrace();
> }
> }
> try {
> while (rs.next()) {
> System.out.println(rs.getRow());
> }
> } catch (final SQLException e1) {
> e1.printStackTrace();
> } finally {
> try {
> rs.close();
> } catch (final SQLException e) {
> e.printStackTrace();
> throw new Error("SQL issue");
> }
> }
> if (ps != null) {
> try {
> ps.close();
> } catch (final SQLException e) {
> e.printStackTrace();
> if (conn != null) {
> try {
> conn.close();
> } catch (final SQLException e1) {
> e1.printStackTrace();
> throw new Error("SQL issue");
> }
> }
> throw new Error("SQL issue");
> }
> }
> if (conn != null) {
> try {
> conn.close();
> } catch (final SQLException e) {
> e.printStackTrace();
> throw new Error("SQL issue");
> }
> }
> return null;
> }
So you want to open a DB connection, run a prepared statement and obtain
a result set. If any of these steps fails along the way, you want to
retry these steps against a different DB URL. Once you have the result
set, you want to run code against it and *not* retry upon failure. And
of course you want to close all resources, no matter what code path has
been taken. Does that capture the intent?
This feels somewhat odd. I can imagine retrying against the mirror when
the primary DB isn't reachable. But if the statement/result fetching
fails on a live primary, why should I hope for better results against
the mirror?
Anyway, just going with it, I'd try to extract exception handling
responsibilities to reusable abstractions that can also be tested
standalone.
Assume you implement the following:
@FunctionalInterface
public interface CheckedFunction<I, O, E extends Exception> {
O apply(I input) throws E;
}
@FunctionalInterface
public interface CheckedSupplier<O, E extends Exception> {
O get() throws E;
}
public static <I, O, E extends Exception> O tryAlternatives(
CheckedFunction<I, O, E> op,
I firstInput,
I... moreInputs
) throws E { ... }
public class CumulativeResource<T extends AutoCloseable>
implements AutoCloseable {
public final T resource;
public interface CumulativeResourceBuilder<T extends AutoCloseable> {
<S extends AutoCloseable> CumulativeResourceBuilder<S>
cumulate(CheckedFunction<T, S, Exception> builder);
CumulativeResource<T> build() throws Exception;
}
public static <T extends AutoCloseable> CumulativeResourceBuilder<T>
from(CheckedSupplier<T, Exception> factory) { ... }
}
Then your actual code might become this:
CumulativeResource<ResultSet> fetchResult(String dbUrl)
throws Exception {
return
CumulativeResource
.from(() -> DriverManager.getConnection(dbUrl, user, password))
.cumulate(c ->
c.prepareStatement(
query,
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY
)
)
.cumulate(PreparedStatement::executeQuery)
.build();
}
void runQuery() throws Exception {
try(CumulativeResource<ResultSet> rsRes =
tryAlternatives(this::fetchResult, firstDbUrl, secondDbUrl)) {
ResultSet rs = rsRes.resource;
while (rs.next()) {
System.out.println(rs.getRow());
}
}
}
Best regards,
Patrick
[toc] | [prev] | [next] | [standalone]
| From | Daniele Futtorovic <da.futt.news@laposte-dot-net.invalid> |
|---|---|
| Date | 2019-04-07 22:14 +0200 |
| Message-ID | <q8dloh$fh9$1@dont-email.me> |
| In reply to | #38873 |
> Assume you implement the following:
>
> @FunctionalInterface
> public interface CheckedFunction<I, O, E extends Exception> {
> O apply(I input) throws E;
> }
>
> @FunctionalInterface
> public interface CheckedSupplier<O, E extends Exception> {
> O get() throws E;
> }
>
> public static <I, O, E extends Exception> O tryAlternatives(
> CheckedFunction<I, O, E> op,
> I firstInput,
> I... moreInputs
> ) throws E { ... }
>
> public class CumulativeResource<T extends AutoCloseable>
> implements AutoCloseable {
> public final T resource;
>
> public interface CumulativeResourceBuilder<T extends AutoCloseable> {
> <S extends AutoCloseable> CumulativeResourceBuilder<S>
> cumulate(CheckedFunction<T, S, Exception> builder);
> CumulativeResource<T> build() throws Exception;
> }
>
> public static <T extends AutoCloseable> CumulativeResourceBuilder<T>
> from(CheckedSupplier<T, Exception> factory) { ... }
> }
>
> Then your actual code might become this:
>
> CumulativeResource<ResultSet> fetchResult(String dbUrl)
> throws Exception {
> return
> CumulativeResource
> .from(() -> DriverManager.getConnection(dbUrl, user, password))
> .cumulate(c ->
> c.prepareStatement(
> query,
> ResultSet.TYPE_SCROLL_INSENSITIVE,
> ResultSet.CONCUR_READ_ONLY
> )
> )
> .cumulate(PreparedStatement::executeQuery)
> .build();
> }
>
> void runQuery() throws Exception {
> try(CumulativeResource<ResultSet> rsRes =
> tryAlternatives(this::fetchResult, firstDbUrl, secondDbUrl)) {
> ResultSet rs = rsRes.resource;
> while (rs.next()) {
> System.out.println(rs.getRow());
> }
> }
> }
Sexy.
--
DF.
[toc] | [prev] | [next] | [standalone]
| From | Andreas Leitgeb <avl@logic.at> |
|---|---|
| Date | 2019-04-04 15:15 +0000 |
| Message-ID | <slrnqac7sl.cfl.avl@logic.at> |
| In reply to | #38863 |
Eric Douglas <e.d.programmer@gmail.com> wrote:
> On Thursday, April 4, 2019 at 9:03:28 AM UTC-4, Eric Sosman wrote:
>> > } finally {
>> > try {
>> > fos.close();
>> Aside: I think you need a null-test here.
> Is a null even possible? It would have to crash in the 'new'.
Exactly! It's the purpose of the "finally" block to be run *also*
in case of an exception in the "try"-block.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.java.programmer
csiph-web