i have a pretty similar while loop in two different functions, how can i write the code that both functions use the same while? the idea is when i go in either of the functions they should implement the behavior of retrying 5 times before giving up.
public Document getHtml(String url) {
int retries = 0;
while (retries < 5) {
try {
return Jsoup.connect(url).get();
} catch(IOException e) {
LOGGER.logWarn("Problem Occured While Downloading The File= " + e.getMessage());
}
retries += 1;
}
return null;
}
#Override
public String getFile(String url) {
int retries = 0;
while(retries < 5) {
try {
URL urlObj = new URL(url);
ByteArrayOutputStream result = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
try (InputStream is = urlObj.openStream()) {
while ((length = is.read(buffer)) != -1) {
result.write(buffer, 0, length);
}
}
return result.toString("UTF-8");
} catch (IOException e) {
LOGGER.logWarn("Problem Occured While Downloading The File= " + e.getMessage());
}
retries += 1;
}
return null;
}
You can extract your retry logic to a higher-order function:
public static <T> T retry5Times(ThrowingSupplier<T, IOException> supplier) {
for(int i = 0; i < 5; i++) {
try {
return supplier.get();
} catch (IOException e) {
LOGGER.logWarn("Problem Occured While Downloading The File= " + e.getMessage());
}
}
return null;
}
Where ThrowingSupplier is:
#FunctionalInterface
public interface ThrowingSupplier<T, E extends Exception> {
T get() throws E;
}
And use it this way:
public Document getHtml(String url) {
return retry5Times(() -> Jsoup.connect(url).get());
}
Related
I have kinda figured out how sockets work but I seem to have run into another wall. I'm supposed to somehow use the socket to transfer the data, but how? when I try it gives me a SocketException bind, saying it's already in use. I used it originally to connect it to a Directory, where I will gather other nodes and then if one doesn't have the data, it will ask for it from the other nodes.
class Download extends Thread {
CloudByte[] list = new CloudByte[1000000];
#Override
public void run() {
try {
var nodes = ConnectingDirectory.getNodes();
for (Nodes node : nodes) {
if ((node.getHostPort() == ConnectingDirectory.getHostIP())) {
downloadFile(node.getHostPort());
}
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
try {
fileWriting(getFile().getName(), list);
} catch (IOException e) {
e.printStackTrace();
}
}
public synchronized void downloadFile(int port) throws IOException, ClassNotFoundException {
while (true) {
ServerSocket ss = ConnectingDirectory.getServerSocket();
Socket socket = ss.accept();
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
for (int j = 0; j <= 9999; j += 1) {
byte[] bit = (byte[]) ois.readObject();
for (int i = 0; i < bit.length; i++) {
list[i + j * 100] = new CloudByte(bit[i]);
}
}
System.out.println("Download Completed");
}
}
This is the function, I'm using to Download the date from the InputStream, the problem I'm having is that it's not downloading unless I restart the other Node. Is there a way to avoid having to do that? I really am at a loss.
Note; the for is because I need to transfer 1000000 bytes, in packets of 100 bytes.
The sending the data is:
class Upload extends Thread {
#Override
public void run() {
if (getFile().exists()) {
var nodes = ConnectingDirectory.getNodes();
for (Nodes node : nodes) {
if (node.getHostPort() == ConnectingDirectory.getHostIP()) {
try {
uploadFile(node.getHostPort());
} catch (IOException e) {
e.printStackTrace();
}
}
}
} else {
new Download().start();
}
}
public static void uploadFile(int hostPort) throws IOException {
Socket socket = new Socket("localhost", hostPort);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
ByteBlockRequest bbr = new ByteBlockRequest(getStoredData());
for (int j = 0; j <= 9999; j += 1) {
objectOutputStream.writeObject(bbr.blocksToSend(j));
}
objectOutputStream.flush();
System.out.println("Uploaded all the Data!");
}
Creating the server socket:
public ConnectingDirectory(String hostName, int hostIP, int directoryIP) throws IOException {
this.hostName = hostName;
this.directoryIP = directoryIP;
ConnectingDirectory.hostIP = hostIP;
this.address = InetAddress.getByName(hostName);
socket = new Socket(address, directoryIP);
serverSocket = new ServerSocket(hostIP);
signUp();
askConnectedNodes();
}
I integrated code to sonarqube for quality code and set method complexity is 4.
Please help me to reduce this for loop complexity to 4
for (int i = 1; i <= retryCount + count; i++) {
try {
if (cat!= null)
grps = cat.getAllGroups(category);
flag = true;
} catch (Exception e) {
if (i >= retryCount + count) {
throw new MyException(new Fault(1009,
new Object[] { e.getMessage() }));
} else {
if (e.getMessage().contains("No Records Found")) {
break;
} else {
String status = handleIOAutomationException(ctx, e);
if (status.equalsIgnoreCase("none")) {
throw new MyException(new Fault(1009,
new Object[] { e.getMessage() }));
} else if (status.equalsIgnoreCase("some")) {
}
}
}
}
if (flag) {
break;
}
}
Try to extract your logic into its own sub methods and try make these shorter. You should also try to make your identifiers more readable.
public void method() {
...
int maxLoops = retryCount + count;
for (int i = 1; i <= maxLoops; i++) {
if (tryToGetAllGroups(maxLoops, i))
break;
}
}
private boolean tryToGetAllGroups(int maxLoops, int i) throws MyException {
try {
if (cat != null)
grps = cat.getAllGroups(category);
return true;
} catch (Exception e) { // you should make Exception more specific!
if (i >= maxLoops) {
return throwFinalException(e);
} else {
if (tryToGetCat(e)) return true;
}
}
return false;
}
private boolean tryToGetCat(Exception e) throws MyException {
if (e.getMessage().contains("No Records Found")) {
return true;
} else {
String status = handleIOAutomationException(ctx, e);
if (status.equalsIgnoreCase("none")) {
throwFinalException(e);
} else if (status.equalsIgnoreCase("some")) {
// try to get cat here
}
}
return false;
}
private boolean throwFinalException(Exception e) throws MyException {
throw new MyException(new Fault(1009,
new Object[]{e.getMessage()}));
}
The problem I am having is acquiring all reachable clients on a network.The below method returns some clients when called. In most cases other android clients.However for the PC it fails when firewall is on.Is there a more effective way to get all clients in Java/android purely or will I need to use android NDK?Any help from experts in this domain will be appreciated.Thanks in advance.
/***
* ping_JavaStyle(final int j)
* uses multi threads to enhance performance
* while pinging from 0>j<=255
* #param j
*/
private void ping_JavaStyle(final int j)
{
new Thread(new Runnable() { // new thread for parallel execution
public void run() {
try {
String testIp = prefix + String.valueOf(j);
InetAddress address = InetAddress.getByName(testIp);
String output = address.toString().substring(1);
if (address.isReachable(3000)) {
System.out.println(output + " is on the network");
ipList.add(testIp);
} else {
if (retest(testIp, 139)) {
ipList.add(testIp);
} else {
System.out.println("Not Reachable: " + output);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}).start();
}
After Researching some more, got this working.With help of this repo:https://github.com/stealthcopter/AndroidNetworkTools
Below code solves the problem:
** RunnableTask.Java
* Created by Kirk on 10/29/2017.
*/
public class RunnableTask implements Callable<Boolean> {
private String testIp = "";
private Boolean is_Reachable = false;
public RunnableTask(String testIp) {
this.testIp = testIp;
}
#Override
public Boolean call() throws Exception {
try {
PingResult pingResult = Ping.onAddress(this.testIp).setTimes(1).setTimeOutMillis(1500).doPing();
if (pingResult.isReachable) {
is_Reachable = true;
}
} catch (UnknownHostException e) {
e.printStackTrace();
}
return is_Reachable;
}
}
And use in the caller method:
private static final int NTHREDS = 255;
//.......
ExecutorService executor = Executors.newFixedThreadPool(NTHREDS);
List<Future<Boolean>> thread_Values_list = new ArrayList<>();
for (int i = 1; i <= 255; i++) {
final int j = i;
try {
try {
String testIp = prefix + String.valueOf(j);
RunnableTask worker = new RunnableTask(testIp);
Future<Boolean> submit = executor.submit(worker);
thread_Values_list.add(submit);
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
}
}
for (Future<Boolean> finishedThread : thread_Values_list) {
String reachable_Ip = "";
try {
if (finishedThread.get()) {
reachable_Ip = prefix + String.valueOf(finishThread_counter);
ipList.add(reachable_Ip);
}
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
finishThread_counter++;
}
executor.shutdown();
}
I am programatically trying to connect to ssh running remotely. I am running a tomcat server instance. Whenever i need, from the code, i create a session, connect and execute a few commands that are needed within a try block and then close off the connection that was created as part of the finally block at all the places. Things work well and fine, but at some cases when i execute a w or netstat command on the ssh server, I see a few connections that are idle for more than a few hours and the ip address of those connections shows the connection to be from my application, but my java heap dump does not show any instance of my class in the memory, but i see ganymed related class instances in the heap.
I am using ganymed-ssh-260 library to connect to my server.
Is this something that someone has already seen?
Attaching the code snippet that connectes the ssh to the server
public class SSHExecutor{
private OutputStream stdin;
private InputStream stdout;
private InputStream stderr;
private Session sess;
private Connection conn;
public void createConnection(String hostname, int port, String userName, String password) throws Exception {
try {
conn = new Connection(hostname, port);
final boolean isAuthenticated = publicKeyAccess(hostname, userName, password);
if (!isAuthenticated) {
throw new IOException("Authentication failed.");
}
sess = conn.openSession();
final int xWidth = 90;
final int yWidth = 80;
sess.requestPTY("dumb", xWidth, yWidth, 0, 0, null);
sess.startShell();
stdin = sess.getStdin();
stdout = sess.getStdout();
stderr = sess.getStderr();
isConnectionActive = true;
final String response = getResponse();
if (response != null && response.toLowerCase().contains(ObjectConstants.CURRENTLY_NOT_AVAILABLE)) {
throw new IOException("Account is currently not available.");
}
} catch (Exception e) {
log.error("Problem in CreateConnection", e);
isConnectionActive = false;
throw e;
}
}
public String getResponse() {
final StringBuffer responseData = new StringBuffer();
try {
final int byteValue = 8192;
final byte[] buffer = new byte[byteValue];
try {
while (true) {
if ((stdout.available() == 0) && (stderr.available() == 0)) {
int conditions = 1;
if (promptString != null && promptString.length() > 0) {
final int fiveThousand = 5000;
conditions = sess.waitForCondition(ChannelCondition.STDOUT_DATA
| ChannelCondition.STDERR_DATA | ChannelCondition.EOF, fiveThousand);
} else {
conditions = sess.waitForCondition(ChannelCondition.STDOUT_DATA
| ChannelCondition.STDERR_DATA | ChannelCondition.EOF,
ObjectConstants.THOUSAND_FIVE_HUNDRED);
}
if ((conditions & ChannelCondition.TIMEOUT) != 0) {
break;
}
if ((conditions & ChannelCondition.EOF) != 0) {
if ((conditions & (ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA)) == 0) {
break;
}
}
}
while (stdout.available() > 0) {
final int len = stdout.read(buffer);
if (len > 0) {
responseData.append(new String(buffer, 0, len));
}
}
while (stderr.available() > 0) {
final int len = stderr.read(buffer);
if (len > 0) {
responseData.append(new String(buffer, 0, len));
}
}
if (promptString != null && promptString.length() > 0) {
if (responseData.indexOf(promptString) != -1) {
break;
}
}
}
} catch (Exception e) {
log.error("Read Error :", e);
}
} catch (Exception e) {
log.error("getResponse Error ", e);
}
return responseData.toString();
}
public String executeCommand(String command) throws IOException {
String response = null;
if (isConnectionActive && stdin != null) {
try {
stdin.write(command.getBytes());
stdin.flush();
response = getResponse();
} catch (IOException ie) {
throw ie;
} catch (Exception e) {
log.error("Exception in executeCommandForPage()", e);
response = e.getMessage();
}
} else {
response = "Connection not active.";
}
return response;
}
public void closeConnection() {
if (stderr != null) {
try {
stderr.close();
} catch (Exception e) {
log.error("Exception in closeConnection()", e);
}
}
if (stdout != null) {
try {
stdout.close();
} catch (Exception e) {
log.error("Exception in closeConnection()", e);
}
}
if (stdin != null) {
try {
stdin.close();
} catch (Exception e) {
log.error("Exception in closeConnection()", e);
}
}
if (sess != null) {
try {
sess.close();
} catch (Exception e) {
log.error("Exception in closeConnection()", e);
}
}
if (conn != null) {
try {
conn.close();
} catch (Exception e) {
log.error("Exception in closeConnection()", e);
}
}
}
}
You're creating a local Connection variable but you're testing what must be a member variable, which is always null, so you're never closing it.
If authentication fails you're leaking the connection.
I'm using the Bluecove library to devolep an Obex ftp client/server on android 2.X.
So far i managed to connect as a client from android to a pc.
I tried the bluecove example code for a server but doesn't work.
Is it possible to develop a server on android 2.X. Does any one have the code to do it.
Thank you.
public class OBEXServer implements Runnable {
private SessionNotifier serverConnection;
private boolean isStoped = false;
private boolean isRunning = false;
public final UUID OBEX_OBJECT_PUSH = new UUID(0x1105);
public static final String SERVER_NAME = "OBEX Object Push";
private UserInteraction interaction;
private OBEXServer(UserInteraction interaction) {
this.interaction = interaction;
}
public static OBEXServer startServer(UserInteraction interaction) {
OBEXServer srv = new OBEXServer(interaction);
Thread thread = new Thread(srv);
thread.start();
while (!srv.isRunning && !srv.isStoped) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new Error(e);
}
}
if (!srv.isRunning) {
throw new Error("Can't start server");
}
return srv;
}
/*
* (non-Javadoc)
*
* #see java.lang.Runnable#run()
*/
public void run() {
isStoped = false;
LocalDevice localDevice;
try {
localDevice = LocalDevice.getLocalDevice();
if (!localDevice.setDiscoverable(DiscoveryAgent.GIAC)) {
Logger.error("Fail to set LocalDevice Discoverable");
}
serverConnection = (SessionNotifier) Connector.open("btgoep://localhost:" + OBEX_OBJECT_PUSH + ";name="
+ SERVER_NAME);
} catch (Throwable e) {
Logger.error("OBEX Server start error", e);
isStoped = true;
return;
}
try {
ServiceRecord record = localDevice.getRecord(serverConnection);
String url = record.getConnectionURL(ServiceRecord.NOAUTHENTICATE_NOENCRYPT, false);
Logger.debug("BT server url: " + url);
final int OBJECT_TRANSFER_SERVICE = 0x100000;
try {
record.setDeviceServiceClasses(OBJECT_TRANSFER_SERVICE);
} catch (Throwable e) {
Logger.debug("setDeviceServiceClasses", e);
}
DataElement bluetoothProfileDescriptorList = new DataElement(DataElement.DATSEQ);
DataElement obbexPushProfileDescriptor = new DataElement(DataElement.DATSEQ);
obbexPushProfileDescriptor.addElement(new DataElement(DataElement.UUID, OBEX_OBJECT_PUSH));
obbexPushProfileDescriptor.addElement(new DataElement(DataElement.U_INT_2, 0x100));
bluetoothProfileDescriptorList.addElement(obbexPushProfileDescriptor);
record.setAttributeValue(0x0009, bluetoothProfileDescriptorList);
final short ATTR_SUPPORTED_FORMAT_LIST_LIST = 0x0303;
DataElement supportedFormatList = new DataElement(DataElement.DATSEQ);
// any type of object.
supportedFormatList.addElement(new DataElement(DataElement.U_INT_1, 0xFF));
record.setAttributeValue(ATTR_SUPPORTED_FORMAT_LIST_LIST, supportedFormatList);
final short UUID_PUBLICBROWSE_GROUP = 0x1002;
final short ATTR_BROWSE_GRP_LIST = 0x0005;
DataElement browseClassIDList = new DataElement(DataElement.DATSEQ);
UUID browseClassUUID = new UUID(UUID_PUBLICBROWSE_GROUP);
browseClassIDList.addElement(new DataElement(DataElement.UUID, browseClassUUID));
record.setAttributeValue(ATTR_BROWSE_GRP_LIST, browseClassIDList);
localDevice.updateRecord(record);
} catch (Throwable e) {
Logger.error("Updating SDP", e);
}
try {
int errorCount = 0;
int count = 0;
isRunning = true;
while (!isStoped) {
RequestHandler handler = new RequestHandler();
try {
count++;
Logger.debug("Accepting OBEX connections");
handler.connectionAccepted(serverConnection.acceptAndOpen(handler));
} catch (InterruptedIOException e) {
isStoped = true;
break;
} catch (Throwable e) {
if ("Stack closed".equals(e.getMessage())) {
isStoped = true;
}
if (isStoped) {
return;
}
errorCount++;
Logger.error("acceptAndOpen ", e);
continue;
}
errorCount = 0;
}
} finally {
close();
Logger.debug("OBEX Server finished!");
isRunning = false;
}
}
public void close() {
isStoped = true;
try {
if (serverConnection != null) {
serverConnection.close();
}
Logger.debug("OBEX ServerConnection closed");
} catch (Throwable e) {
Logger.error("OBEX Server stop error", e);
}
}
private static File homePath() {
String path = "bluetooth";
boolean isWindows = false;
String sysName = System.getProperty("os.name");
if (sysName != null) {
sysName = sysName.toLowerCase();
if (sysName.indexOf("windows") != -1) {
isWindows = true;
path = "My Documents";
}
}
File dir;
try {
dir = new File(System.getProperty("user.home"), path);
if (!dir.exists()) {
if (!dir.mkdirs()) {
throw new SecurityException();
}
}
} catch (SecurityException e) {
dir = new File(new File(System.getProperty("java.io.tmpdir"), System.getProperty("user.name")), path);
}
if (isWindows) {
dir = new File(dir, "Bluetooth Exchange Folder");
}
if (!dir.exists()) {
if (!dir.mkdirs()) {
return null;
}
} else if (!dir.isDirectory()) {
dir.delete();
if (!dir.mkdirs()) {
return null;
}
}
return dir;
}
private void showStatus(final String message) {
interaction.showStatus(message);
}
private class RequestHandler extends ServerRequestHandler {
Timer notConnectedTimer = new Timer();
boolean isConnected = false;
boolean receivedOk = false;
Connection cconn;
void connectionAccepted(Connection cconn) {
Logger.debug("Received OBEX connection");
showStatus("Client connected");
this.cconn = cconn;
if (!isConnected) {
notConnectedTimer.schedule(new TimerTask() {
public void run() {
notConnectedClose();
}
}, 1000 * 30);
}
}
void notConnectedClose() {
if (!isConnected) {
Logger.debug("OBEX connection timeout");
try {
cconn.close();
} catch (IOException e) {
}
if (!receivedOk) {
showStatus("Disconnected");
}
}
}
public int onConnect(HeaderSet request, HeaderSet reply) {
isConnected = true;
notConnectedTimer.cancel();
Logger.debug("OBEX onConnect");
return ResponseCodes.OBEX_HTTP_OK;
}
public void onDisconnect(HeaderSet request, HeaderSet reply) {
Logger.debug("OBEX onDisconnect");
if (!receivedOk) {
showStatus("Disconnected");
}
}
public int onSetPath(HeaderSet request, HeaderSet reply, boolean backup, boolean create) {
Logger.debug("OBEX onSetPath");
return super.onSetPath(request, reply, backup, create);
}
public int onDelete(HeaderSet request, HeaderSet reply) {
Logger.debug("OBEX onDelete");
return super.onDelete(request, reply);
}
public int onPut(Operation op) {
Logger.debug("OBEX onPut");
try {
HeaderSet hs = op.getReceivedHeaders();
String name = (String) hs.getHeader(HeaderSet.NAME);
if (name != null) {
Logger.debug("name:" + name);
showStatus("Receiving " + name);
} else {
name = "xxx.xx";
showStatus("Receiving file");
}
Long len = (Long) hs.getHeader(HeaderSet.LENGTH);
if (len != null) {
Logger.debug("file lenght:" + len);
interaction.setProgressValue(0);
interaction.setProgressMaximum(len.intValue());
}
File f = new File(homePath(), name);
FileOutputStream out = new FileOutputStream(f);
InputStream is = op.openInputStream();
int received = 0;
while (!isStoped) {
int data = is.read();
if (data == -1) {
Logger.debug("EOS received");
break;
}
out.write(data);
received++;
if ((len != null) && (received % 100 == 0)) {
interaction.setProgressValue(received);
}
}
op.close();
out.close();
Logger.debug("file saved:" + f.getAbsolutePath());
showStatus("Received " + name);
receivedOk = true;
return ResponseCodes.OBEX_HTTP_OK;
} catch (IOException e) {
Logger.error("OBEX Server onPut error", e);
return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
} finally {
Logger.debug("OBEX onPut ends");
interaction.setProgressDone();
}
}
public int onGet(Operation op) {
Logger.debug("OBEX onGet");
try {
HeaderSet hs = op.getReceivedHeaders();
String name = (String) hs.getHeader(HeaderSet.NAME);
return ResponseCodes.OBEX_HTTP_NOT_IMPLEMENTED;
} catch (IOException e) {
Logger.error("OBEX Server onGet error", e);
return ResponseCodes.OBEX_HTTP_UNAVAILABLE;
} finally {
Logger.debug("OBEX onGet ends");
}
}
public void onAuthenticationFailure(byte[] userName) {
Logger.debug("OBEX AuthFailure " + new String(userName));
}
}
}