Using two while loop or single loop for different resultsets - java

Here is what I have right now where, I am making multiple JDBC connections based on the IP address I have.
Map<String,Connection> connections = new HashMap<>();
DeviceStmt = connRemote.createStatement();
DeviceRS = DeviceStmt.executeQuery(maindbsql);
while (DeviceRS.next()) {
try {
final String ip_address = DeviceRS.getString("IP_vch");
System.out.println("Value of IP_vch Field:"+ip_address);
connections.put(ip_address,DriverManager.getConnection("jdbc:mysql://"
+ ip_address + ":3306/test",RemoteUser,RemotePass));
if (connections.isEmpty()) {
System.err.println("Not successfull");
} else {
System.out.println("Connection to"+ip_address+"is successfull");
}
} catch(SQLException ex1) {
System.out.println("While Loop Stack Trace Below:");
ex1.printStackTrace();
}
}//END Of while(DeviceRS.next())
What I want to have :
Say for example I am making connections to following IP's : 11.11.1.111 and 22.22.2.222
I want to excute an additional query on 11.11.1.111 just after connection is established after the following line in the above code:
connections.put(ip_address,DriverManager.getConnection("jdbc:mysql://" + ip_address + ":3306/test",RemoteUser,RemotePass));
Since, I can't use the same resultset(DeviceRS) which I have already used , I am wondering how can I run a different query.
I want to do something like the following:
DeviceStmttwo = connRemote.createStatement();
DeviceRStwo = DeviceStmttwo.executeQuery(maindbsqlnew);
below the following code I mentioned in the above code:
DeviceStmt = connRemote.createStatement();
DeviceRS = DeviceStmt.executeQuery(maindbsql);
Should I go for different while(DeviceRStwo.next()) option just before the existing while(DeviceRS.next()) loop and make connections again which seems to be a overhead to me.

Related

Synchronized List keeps locking permanently

I have created a Server with ServerSocket and any connection made is put into a List of Connection. The list is synchronized (Collections.synchronizedList(new ArrayList<Connection>())), and I access it properly such as:
synchronized(getConnections()) {
Iterator<Connection> it = getConnections().iterator();
while(it.hasNext()) {
try {
if(!it.next().keepAlive()) {
it.remove();
}
}catch(Exception error) {
ErrorLogger.error(error);
}
}
}
BUT it locks up somewhere at random times. Once it locks, it remains locked forever.
I have created a logging system which logs a message before and after every synchronized block used for this list. (COMPLETE means it went through the synchronized block). Pastebin of the logs with descriptions.
Here is my code for the ADDED part seen in the logs:
DebugFile.write("ADDED connection");
//This is used to dump empty connections
synchronized(getConnections()) {//Synchronized
getConnections().add(mini);//Adding to List
Iterator<Connection> it = getConnections().iterator();
while(it.hasNext()) {
Connection con = it.next();
if(con.getSocket() == null || !con.getSocket().isConnected() ||
(con.getBungeeServer().equals("Unknown") && System.currentTimeMillis() > con.getCreateTime()+30000)){
System.out.println("[MoltresBungee] Connection disconnecting because they have not identified within 30 seconds.");
con.stop(false);
it.remove();//Removes expired sessions
}
}
Bungee.instance.getLogger().info("MoltresBungee - Active connections: " + getConnections().size());
}
DebugFile.write("ADDED connection - COMPLETE");//Logs complete
Here is code for REMOVE ALL:
DebugFile.write("REMOVE ALL : " + name);
synchronized(getConnections()) {
Iterator<Connection> it = getConnections().iterator();
while(it.hasNext()) {
Connection con = it.next();
if(con == null || con.getSocket() == null || con.getSocket().isClosed() || con.getBungeeServer().equals(name)){
DebugFile.write("REMOVE ALL : " + name + " removing: " + con.getBungeeServer());
if(con != null && con.getSocket() != null) {
try{
con.getSocket().close();
}catch(Exception e){ErrorLogger.error(e);}
}
it.remove();
}
}
}
DebugFile.write("REMOVE ALL : " + name + " - COMPLETE");
The adding code is suppose to add a connection to this list then remove any items in this list which have lost connection or never completed the handshake.
The remove all code is suppose to remove anything from the list that has the same name or has closed already.
I have about ten more places I used the synchronized(getConnections()) like what is above.
If needed, here is getConnections() method:
public synchronized List<Connection> getConnections(){
return connections;
}
Why is this locking, and how do I fix it?
EDIT:
Also, clients attempting to connect retry over and over until connected, and it seems that all the previous tries are still there when the server turns on. This is when the list locks as well.

Use dnsjava to get hostname from ip address from 192.168.1.1 to 192.168.1.254

I am trying to use dnsjava in an android app to find hostnames of devices in my local wifi network.
Below is the code used:
try
{
String ipAddress = "33.1.168.192";
String dnsblDomain = "in-addr.arpa";
Record[] records;
Lookup lookup = new Lookup(ipAddress + "." + dnsblDomain, Type.PTR);
SimpleResolver resolver = new SimpleResolver();
resolver.setAddress(InetAddress.getByName("192.168.1.1"));
lookup.setResolver(resolver);
records = lookup.run();
if(lookup.getResult() == Lookup.SUCCESSFUL)
{
for (int i = 0; i < records.length; i++)
{
if(records[i] instanceof PTRRecord)
{
PTRRecord ptr = (PTRRecord) records[i];
System.out.println("DNS Record: " + records[0].rdataToString());
}
}
} else {
System.out.println("Failed lookup");
}
}
catch(Exception e)
{
System.out.println("Exception: " + e);
}
The code was taken from the below link and it seems to work there for OP:
any way to discover Android devices on your network?
192.168.1.33 is an active device on my wifi network . 192.168.1.1 is the router IP . The code reaches "Failed lookup" everytime .
I am not sure where I am going wrong as I am new to dnsJava and Networks.
An additional question is , will this yield perfect result when scanned over all 254 ip's ? I am thinking of using this code in prod and need to be sure of that .
Any help is very much appreciated.
PTR records for reverse names are not stored in the order you're thinking. In general terms for IP A.B.C.D you need to resolve D.C.B.A.in-addr.arpa, so you'll need to reverse the order of the IP components.

for-loop doesn't work in android try-catch block

I am making database of my school's building and classroom with Realm. But, 'for-loop' in try-catch doesn't work:
public void startCheckRealm() {
// Writing DataBase with Realm
try {
Log.d("Realm", "Init");
InitializeAPI.init_BuildingRoom(getActivity().getApplicationContext());
Log.d("Realm", "Complete");
} catch(Exception e) {
e.printStackTrace();
}
// Trying to check the Database whether it is right or wrong
try {
Log.d("Realm Test", "2nd Try Catch");
Realm.init(getActivity().getApplicationContext());
Realm realm = Realm.getDefaultInstance();
RealmResults<BuildingList> buildingLists = realm.where(BuildingList.class).findAllSorted("buildingCode");
int totalNumber = 0;
for(int i = 0; i < buildingLists.size(); i++) {
Log.d("For", "index = " + i);
RealmResults<RoomList> rooms = buildingLists.get(i).getRoomList().sort("roomCode");
String BuildingName = buildingLists.get(i).getBuildingName();
String BuildingCode = buildingLists.get(i).getBuildingCode();
for(int idx = 0; idx < rooms.size(); idx++) {
totalNumber++;
String RoomCode = rooms.get(idx).getRoomCode();
String RoomName = rooms.get(idx).getRoomName();
Log.d("Realm Test", "Number :: " + String.valueOf(totalNumber) + " BuildingCode :: " + BuildingCode + "\t\t BuildingName :: " + BuildingName + "\t\t RoomCode :: " + RoomCode + "\t\t RoomName :: " + RoomName);
}
}
Log.d("Realm Test", "2nd Try Catch Complete + " + String.valueOf(totalNumber));
} catch(RealmException e) {
e.printStackTrace();
}
}
In the first try-catch, the method, which does making database, is complete without Exception. I was curious whether this database is right or wrong.
So, in 2nd try-catch, I was trying to check realm files with queries.
The problem is "for-loop" doesn't work in 2nd try-catch. Below snippet is my logcat.
D/Realm: Init
I/System.out: bdList getLength :: 52
I/System.out: roomList getLength :: 2376
D/Realm: Complete
D/Realm Test: 2nd Try Catch
D/Realm Test: 2nd Try Catch Complete + 0
I want to check my realm data with Log but, doesn't work as you can see.
If there is no problem, the logcat shows lots of my building and room lists and ends with "D/Realm Test: 2nd Try Catch Complete + 2376".
Could you explain the reason why it doesn't work? I cannot understand the reason why it doesn't work even though there is no Exception.
While in your use-case this doesn't pose a problem, when you're iterating a RealmResults inside a transaction, the results are live in every version <= 0.88.3 and >= 3.0.0.
So in that case,
RealmResults<BuildingList> buildingLists = realm.where(BuildingList.class).findAllSorted("buildingCode");
for(int i = 0; i < buildingLists.size(); i++) {
BuildingList buildingList = buildingLists.get(i); // <-- !!!
will fail (it will skip every second item!)
So you should use iterators instead (3.0.0+! on <= 0.88.3 you'd do reverse iteration)
RealmResults<BuildingList> buildingLists = realm.where(BuildingList.class).findAllSorted("buildingCode");
for(BuildingList buildingList : buildingLists) { // <-- !!!
The reason why this works is because iterators by default create a new snapshot collection (3.0.0+), and iterating by index on a snapshot also works
OrderedRealmCollection<BuildingList> snapshot = buildingLists.createSnapshot();
for(int i = 0; i < ...
Simple: there is no exception thrown; and you only have your print statements inside the loop.
Thus the one and only conclusion: at that point in time when your for loops are executed, the corresponding list is empty. Therefore the loop body is not entered; nothing gets printed. And that has nothing to do with the fact that this loop is within a try-catch block.
That is all there is to this. So, the direct answer is: print the list size directly in front of the loop to avoid such surprises.
(of course, the interesting part is to understand what happens to the list which seems to be non-empty earlier on - but in order to debug that, you would have to add more of your code).
Two inputs:
1.Haven't used realm but looks like the syntax for getting sorted entriesis a bit different Official documentation
2.If the above point is wrong than from your code it looks like buildingList size is zero. Have you tried checking the size?
Let me know the results.
Try logging your catch block. Chances are the rest of the code including the loop didn't complete because your app was caught with the Exception.
You should debug buildingLists.size(); before for loop
Log.d("Building List Size ", buildingLists.size()+"");
In that case you can find the value of buildingLists.size();

JAVA code to use semaphore with Cassandra to throttle executeAsync writes to eliminate NoHostAvailableException errors

I have some basic code that uses a prepared statement in a for loop and writes the result into a Cassandra Table with some throttling using a semaphore.
Session session = null;
try {
session = connector.openSession();
} catch( Exception ex ) {
// .. moan and complain..
System.err.printf("Got %s trying to openSession - %s\n", ex.getClass().getCanonicalName(), ex.getMessage() );
}
if( session != null ) {
// Prepared Statement for Cassandra Inserts
PreparedStatement statement = session.prepare(
"INSERT INTO model.base " +
"(channel, " +
"time_key, " +
"power" +
") VALUES (?,?,?);");
BoundStatement boundStatement = new BoundStatement(statement);
//Query Cassandra Table that has capital letters in the column names
ResultSet results = session.execute("SELECT \"Time_Key\",\"Power\",\"Bandwidth\",\"Start_Frequency\" FROM \"SB1000_49552019\".\"Measured_Value\" limit 800000;");
// Get the Variables from each Row of Cassandra Data
for (Row row : results){
// Upper Case Column Names in Cassandra
time_key = row.getLong("Time_Key");
start_frequency = row.getDouble("Start_Frequency");
power = row.getFloat("Power");
bandwidth = row.getDouble("Bandwidth");
// Create Channel Power Buckets, place information into prepared statement binding, write to cassandra.
for(channel = 1.6000E8; channel <= channel_end; channel+=increment ){
if( (channel >= start_frequency) && (channel <= (start_frequency + bandwidth)) ) {
ResultSetFuture rsf = session.executeAsync(boundStatement.bind(channel,time_key,power));
backlogList.add( rsf ); // put the new one at the end of the list
if( backlogList.size() > 10000 ) { // wait till we have a few
while( backlogList.size() > 5432 ) { // then harvest about half of the oldest ones of them
rsf = backlogList.remove(0);
rsf.getUninterruptibly();
} // end while
} // end if
} // end if
} // end for
} // end "row" for
} // end session
My connection is built with the following:
public static void main(String[] args) {
if (args.length != 2) {
System.err.println("Syntax: com.neutronis.Spark_Reports <Spark Master URL> <Cassandra contact point>");
System.exit(1);
}
SparkConf conf = new SparkConf();
conf.setAppName("Spark Reports");
conf.setMaster(args[0]);
conf.set("spark.cassandra.connection.host", args[1]);
Spark_Reports app = new Spark_Reports(conf);
app.run();
}
With this code im attempting to use a semaphore but my Cassandra Cluster still seems to get overloaded and kick out the error:
ERROR ControlConnection: [Control connection] Cannot connect to any
host, scheduling retry in 1000 milliseconds Exception in thread "main"
com.datastax.driver.core.exceptions.NoHostAvailableException: All
host(s) tried for query failed (no host was tried)
It seems odd that it says no host was tried.
I've looked at other semaphore throttling issues such as this and this and attempted to apply to my code above but am still getting the error.
Read my answer to this question for how to back-pressure when using asynchronous calls: What is the best way to get backpressure for Cassandra Writes?

Android application exits without any exception

I'm building an application that shows in a WebView some remote data that is cached in SQLite db. The data is being requested by JavaScript function from WebView via JavaScript interface.
When user types into an input element on the page, JavaScript function requests search result by calling Java function, which in turn fires a sql query. Results are then packaged in suitable JSON format and returned.
Fetching data works OK unless you type very quickly. If you type quick enough after few key presses the app quits WITHOUT any exceptions being thrown, it just goes back to home screen.
I have managed to narrow down the cause - commenting out the call to .query method prevents crashing, but renders app useless.
Is there a way to check what caused application to quit, another log or tool that could help?
Java function code:
public Lot[] getLotList(String query, int limitCount) {
...
...
String[] resultColumns = new String[] { LotsSearch._ID };
String queryWhere = LotsSearch.TABLE_NAME + " MATCH ?";
String[] queryArgs = new String[] { query + "*" };
String sortOrder = LotsSearch.COLUMN_NAME_NUMBER + " ASC, " + LotsSearch.COLUMN_NAME_TITLE + " ASC";
String limit = null;
Cursor cursor = null;
if (limitCount != -1)
limit = "0," + limitCount;
try {
cursor = mDb.query(LotsSearch.TABLE_NAME, resultColumns, queryWhere, queryArgs, null, null, sortOrder, limit);
if (cursor != null && cursor.moveToFirst()) {
result = new Lot[cursor.getCount()];
try {
int idColumnIndex = cursor.getColumnIndexOrThrow(LotsSearch._ID);
int lotId;
Lot lot;
do {
lotId = cursor.getInt(idColumnIndex);
lot = mLots.get(lotId);
if (lot != null)
result[index++] = lot;
} while (cursor.moveToNext());
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
}
} catch (SQLiteException e) {
e.printStackTrace();
} finally {
if (cursor != null)
cursor.close();
}
...
...
return result;
}
UPDATE:
I have discovered that there is another log that could be accessed by issuing
logcat -b events
when the app crashes there is just one entry
I/am_proc_died( 59): [11473,com.example.app]
and when the app exits gracefuly this log shows set of entries:
I/am_finish_activity( 59): [1157978656,22,com.example.app/.MainActivity,app-request]
I/am_pause_activity( 59): [1157978656,com.example.app/.MainActivity]
I/am_on_paused_called(11473): com.example.app.MainActivity
I/am_destroy_activity( 59): [1157978656,22,com.example.app/.MainActivity]
I'd make a change to my auto search function. Namely, only perform the search if the user hasn't pressed a key for about 1/2 a second.
If you are typing fast, then this function is being executed several times right on top of itself, before the results are even able to come back. Meanwhile you are probably have too many cursor resources going at once causing the app to just completely fail.
update. If you consider it, typing 10 keys fairly quickly in a row could potentially mean that you have 10 different queries executing and parsing results... There could certainly be some deadlocking issues with the code that actually calls the getLotList method if it's spun multiple threads to try and update the UI. This can lead to some programs simply giving up the ghost not knowing what to do or even what thread to report the issue on.
Of course, all of that's hard to tell from the small snippet we have.

Categories

Resources