I want to get a file from unix system to my local system which is on windows using java. I'm very much new to this concept. Any ideas on how it could be done? Which is the best java API for this task?
If the Unix machine supports SFTP, JSch is an option. You could adapt the following code to meet your needs:
private static final String USER_PROMPT = "Enter username#hostname:port";
private static final boolean USE_GUI = true;
public static void main(final String[] arg) {
Session session = null;
ChannelSftp channelSftp = null;
try {
final JSch jsch = new JSch();
final String defaultInput = System.getProperty("user.name") + "#localhost:22";
String input = (USE_GUI) ? JOptionPane.showInputDialog(USER_PROMPT, defaultInput) : System.console().readLine("%s (%s): ", USER_PROMPT, defaultInput);
if (input == null || input.trim().length() == 0) {
input = defaultInput;
}
final int indexOfAt = input.indexOf('#');
final int indexOfColon = input.indexOf(':');
final String user = input.substring(0, indexOfAt);
final String host = input.substring(indexOfAt + 1, indexOfColon);
final int port = Integer.parseInt(input.substring(indexOfColon + 1));
jsch.setKnownHosts("/path/to/known_hosts");
// if you have set up authorized_keys on the server, using that identitiy
// with the code on the next line allows for password-free, trusted connections
// jsch.addIdentity("/path/to/id_rsa", "id_rsa_password");
session = jsch.getSession(user, host, 22);
final UserInfo ui = new MyUserInfo();
session.setUserInfo(ui);
session.connect();
channelSftp = (ChannelSftp) session.openChannel("sftp");
channelSftp.connect();
channelSftp.get("/remotepath/remotefile.txt", "/localpath/localfile.txt");
} finally {
if (channelSftp != null) {
channelSftp.exit();
}
if (session != null) {
session.disconnect();
}
}
}
public static class MyUserInfo implements UserInfo {
private String password;
#Override
public String getPassword() {
return password;
}
#Override
public boolean promptYesNo(final String str) {
final Object[] options = {"yes", "no"};
final boolean yesNo = (USE_GUI) ? JOptionPane.showOptionDialog(null, str, "Warning", JOptionPane.DEFAULT_OPTION, JOptionPane.WARNING_MESSAGE, null, options, options[0]) == 0 : System.console().readLine("Enter y or n: ").equals("y");
return yesNo;
}
#Override
public String getPassphrase() {
return null;
}
#Override
public boolean promptPassphrase(final String message) {
return true;
}
#Override
public boolean promptPassword(final String message) {
if (!USE_GUI) {
password = new String(System.console().readPassword("Password: "));
return true;
} else {
final JTextField passwordField = new JPasswordField(20);
final Object[] ob = {passwordField};
final int result = JOptionPane.showConfirmDialog(null, ob, message, JOptionPane.OK_CANCEL_OPTION);
if (result == JOptionPane.OK_OPTION) {
password = passwordField.getText();
return true;
} else {
return false;
}
}
}
#Override
public void showMessage(final String message) {
if (!USE_GUI) {
System.console().printf(message);
} else {
JOptionPane.showMessageDialog(null, message);
}
}
}
I have found JSch to be very useful and straight foreword. Below is a snippet of code written to put all .txt files in a given folder on the sftp server.
public static void sftpConnection() {
// Object Declaration.
JSch jsch = new JSch();
Session session = null;
Channel channel = null;
// Variable Declaration.
String user = "foo";
String host = "10.9.8.7";
Integer port = 22;
String password = "test123";
String watchFolder = "\\localhost\textfiles";
String outputDir = "/remote/textFolder/";
String filemask = "*.txt";
try {
session = jsch.getSession(user, host, port);
/*
* StrictHostKeyChecking Indicates what to do if the server's host
* key changed or the server is unknown. One of yes (refuse connection),
* ask (ask the user whether to add/change the key) and no
* (always insert the new key).
*/
session.setConfig("StrictHostKeyChecking", "no");
session.setPassword(password);
session.connect();
channel = session.openChannel("sftp");
channel.connect();
ChannelSftp sftpChannel = (ChannelSftp)channel;
// Go through watch folder looking for files.
File[] files = findFile(watchFolder, filemask);
for(File file : files) {
// Upload file.
putFile(file, sftpChannel, outputDir);
}
} finally {
sftpChannel.exit();
session.disconnect();
}
}
public static void putFile(File file, ChannelSftp sftpChannel, String outputDir) {
FileInputStream fis = null;
try {
// Change to output directory.
sftpChannel.cd(outputDir);
// Upload file.
fis = new FileInputStream(file);
sftpChannel.put(fis, file.getName());
fis.close();
} catch{}
}
public static File[] findFile(String dirName, final String mask) {
File dir = new File(dirName);
return dir.listFiles(new FilenameFilter() {
public boolean accept(File dir, String filename)
{ return filename.endsWith(mask); }
} );
}
First thing that goes into my mind is FTP.
There are multiple choices to do that. First one simple socket communication between a java client and a server. If you want to go with this approach then follow this:
http://mrbool.com/file-transfer-between-2-computers-with-java/24516
Then there are other high level protocols implementations that can be used such as FTP, HTTP, etc
Follow a related SO post for java FTP client server: FTP client server model for file transfer in Java
Related
I am having issues running multiple SSH jobs (using JSch) with ExecutorService.
When running a single job, they execute as expected. However, when I attempt to run multiple jobs, only the first job executes fully. I have changed the thread pool to use only 1 thread, thinking that somehow its a port issue but it still doesn't work correctly. Any help will be appreciated.
ExecutorService ex = Executors.newFixedThreadPool(4);
Set<Future<Task>> set = new HashSet<Future<Task>>();
for (int i = 0; i < tasks.size(); i++) {
Task task = tasks.get(i);
creds.setHostName(task.getFirewall().getAddress());
System.out.println("Task(" + i + ")=" + task);
Callable<Task> worker = new SSH.SSHWorker(creds, task, i);
ex.submit(worker);
}
Here is the SSH
public class SSH {
LoginCredentials creds;
//ChannelExec channelExec;
ChannelExec channelExec;
BufferedReader consoleOutput;
Session session;
InputStream is;
UI ui;
String output = "";
// String command;
public boolean debug = false;
public SSH(LoginCredentials creds, String command) throws JSchException, IOException {
// System.out.println("NEW SSH");
this.creds = creds;
consoleOutput = new BufferedReader(new InputStreamReader(System.in));
ui = new UI();
this.connect();
Channel channel = session.openChannel("exec");
this.sendCommand(channel, command);
}
public String getOutput() {
return output;
}
public class UI extends MyUserInfo {
String message;
#Override
public void showMessage(String message) {
this.message = message;
super.showMessage(message); //To change body of generated methods, choose Tools | Templates.
}
#Override
public String getMessage() {
return this.message;
}
}
private void sendCommand(Channel channel, String command) throws IOException, JSchException {
this.channelExec = (ChannelExec) channel;
this.channelExec.setCommand(command);
//channel.setInputStream(null);
channel.setOutputStream(System.out);
this.is = channel.getInputStream();
channel.connect();
byte[] buffer = new byte[1024];
while (channel.getExitStatus() == -1) {
//System.out.println("Here 1.1");
while (is.available() > 0) {
//System.out.println("Here 1.2");
int i = is.read(buffer, 0, 1024);
//System.out.println("i= " + i);
if (i < 0) {
System.out.println("breaking");
break;
}
String string = new String(buffer, 0, i);
output = output.concat(string);
//System.out.println("output= "+output);
if (string.contains("Command authorization failed")) {
channel.disconnect();
break;
}
}
if (channel.isClosed()) {
System.out.println("exit-status: " + channel.getExitStatus());
break;
}
}
is.close();
channel.disconnect();
this.session.disconnect();
}
private void connect() throws JSchException {
JSch jsch = new JSch();
session = jsch.getSession(creds.getUser(), creds.getHostName(), 22);
session.setTimeout(0);
session.setPassword(creds.getPassword());
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.setUserInfo(ui);
session.connect();
System.out.println("Connected in SSH");
}
public static class SSHWorker implements Callable {
private LoginCredentials lc;
private Task t;
private int thread;
public SSHWorker(LoginCredentials creds, Task task, int thread) {
this.t = task;
lc = creds;
this.thread = thread;
System.out.println("Creds= " + lc.getHostName() + " Task= " + t + " Thread-" + thread);
}
#Override
public Task call() throws JSchException, IOException {
System.out.println("Doing Call For: Creds= " + lc.getHostName() + " Task= " + t + " Thread-" + thread);
String enablepassword1 = (String) lc.getEnablePassword().get(0);
SSH ssh = new SSH(lc, t.getSSHCommand(enablepassword1));
this.t.setTaskResult(ssh.getOutput());
return t;
}
}
}
The output is Here (IP addresses have been changed)
In your loop that creates the tasks, you use only one instance of LoginCredentials. So all tasks share the instance. In the loop, you overwrite the hostname in each iteration. So in the end the LoginCredentials refers to the hostname of the last task. So all tasks connect to that host.
Just to do not pass the hostname via LoginCredentials and use task.getFirewall().getAddress() directly when creating the JSch session:
SSH ssh = new SSH(lc, t.getSSHCommand(enablepassword1), task.getFirewall().getAddress());
...
public SSH(LoginCredentials creds, String command, String hostname)
{
...
this.connect(hostname);
}
...
private void connect(String hostname) throws JSchException {
JSch jsch = new JSch();
session = jsch.getSession(creds.getUser(), hostname, 22);
...
}
In case of file upload fails then how to do multiple attempts while doing SFTP by using JSCH API?
How to ensure file is uploaded successfully?
How to create thread-safe file upload utility?
Create a common static utility method which can be invoked from the external class. This method has a map argument to persist the values of sFTPUser, sFTPHost, sFTPPort, sFTPPwd, destinationLocation and uploadedFileName :
public static void doSFTP(Map<String, String> ftpParameters) {
if (ftpParameters.get("ID_NAME").equals(
NAPSCommonConstants.MFT_NAPSGPCS_INTF)) {
// do sftp for NAPS GPCS Interface.
uploadUsingSFTP(ftpParameters);
}
}
Use synchronized method to ensure thread safety:
private static synchronized void uploadUsingSFTP(
Map<String, String> ftpPrameterList) {
new SFTPUtility().uploadFileMFT(ftpPrameterList.get("sFTPUser"),
ftpPrameterList.get("sFTPHost"), new Integer(ftpPrameterList
.get("sFTPPort")), ftpPrameterList.get("sFTPPwd"),
ftpPrameterList.get("sourceLocation"), ftpPrameterList
.get("destinationLocation"), ftpPrameterList
.get("uploadedFileName"));
}
Responsible method to upload files using SFTP with 5 attempts:
private void uploadFileMFT(String sFTPUser, String sFTPHost, int sFTPPort,
String sFTPPwd, String sourceLocation, String destinationLocation,
String uploadedFileName) {
LOG.info("Inside uploadFileMFT to upload and verify the file.");
JSch jsch = new JSch();
Vector<String> fileList = null;
/** 5 re-attempt logic to get session */
int attempts = 0;
boolean successfulConnect;
do {
try {
successfulConnect = true;
session = jsch.getSession(sFTPUser, sFTPHost, sFTPPort);
LOG.debug("session connected ...");
session.setPassword(sFTPPwd);
Properties config = new Properties();
config.put("StrictHostKeyChecking", "no");
session.setConfig(config);
session.connect();
LOG.debug("Sftp Session connected ...");
channel = session.openChannel("sftp");
LOG.debug("Sftp Channel opened ...");
channelSftp = (ChannelSftp) channel;
channelSftp.connect();
LOG.info(" Sftp channel opened and connected ...");
channelSftp.put(sourceLocation, destinationLocation);
fileList = channelSftp.ls(destinationLocation);
} catch (JSchException e) {
++attempts;
successfulConnect = false;
LOG.error(e);
} catch (SftpException e) {
++attempts;
successfulConnect = false;
LOG.error(e);
} finally {
if (null != channelSftp) {
channelSftp.exit();
LOG.debug(" sftp Channel exited.");
}
if (null != channel) {
channel.disconnect();
LOG.debug(" Channel disconnected.");
}
if (null != session) {
session.disconnect();
LOG.debug(" Host Session disconnected.");
}
}
} while (attempts < 5 && successfulConnect == false);
fileUploadValidation(fileList, uploadedFileName);
LOG.info("Exiting from method - uploadFileMFT ...");
}
Finally uploaded file can be validated:
private void fileUploadValidation (Vector<String> fileList, String uploadedFileName){
boolean isFileExistis = false;
Object[] objArr = fileList.toArray();
for (int i = 0; i < objArr.length; i++) {
String fileName = objArr[i].toString();
isFileExistis = fileName.contains(uploadedFileName);
if (isFileExistis) {
LOG.info("Uploaded file '" + uploadedFileName + "' was transferred successfull ...");
break;
}else if(i >= objArr.length){
LOG.info("Uploaded file '" + uploadedFileName + "' was failed to transfer ...");
}
}
}
Using jsch
when i run the following cmd 'sudo su -' the program hangs
[TestNG] Running:
C:\Users\brian.crosby\AppData\Local\Temp\testng-eclipse-952620154\testng-customsuite.xml
[root#tbx2-toy-1 ~]#
It looks like the "sudo su -" worked becasue the output states "[root#tbx2-toy-1 ~]#" but when i send it another cmd it is unresponsive.
heres the code:
package com.linux;
import java.io.InputStream;
import org.testng.annotations.*;
import com.jcraft.jsch.*;
import com.thoughtworks.selenium.*;
public class LinuxConnection extends SeleneseTestBase{
String host = null;
private StringBuilder strFileData;
String randomFileName = null;
public String getFileData() {
return strFileData.toString();
}
public String getRandomFileName() {
return randomFileName;
}
public LinuxConnection() {
strFileData = new StringBuilder();
}
#Test
public void createUpdateTBX2FileData(String command)throws Exception {
try {
JSch jsch = new JSch();
host = "brian-crosby#************.net";
String user = host.substring(0, host.indexOf('#'));
host = host.substring(host.indexOf('#') + 1);
Session session = jsch.getSession(user, host, 22);
UserInfo ui = new MyUserInfo();
session.setUserInfo(ui);
session.connect();
ChannelExec channel = (ChannelExec)session.openChannel("exec");
((ChannelExec)channel).setPty(true);
((ChannelExec) channel).setCommand(command);
((ChannelExec) channel).setErrStream(System.err);
InputStream in = channel.getInputStream();
channel.connect();
byte[] tmp = new byte[2048];
while (in.read(tmp, 0, 2048) > 0) {
String str = new String(tmp);
strFileData.append(str);
System.out.println(strFileData);
}
in.close();
channel.disconnect();
session.disconnect();
} catch (Exception e) {
System.out.println(e);
}
}
public static class MyUserInfo implements UserInfo {
public String getPassword() {
return "********";
}
public boolean promptYesNo(String str) {
str = "Yes";
return true;
}
String passwd;
public String getPassphrase() {
return null;
}
public boolean promptPassphrase(String message) {
return true;
}
public boolean promptPassword(String message) {
passwd = "*******";
return true;
}
public void showMessage(String message) {
}
}
}
Here is where i am sending the cmds:
package com.linux;
import org.testng.annotations.*;
public class testLinuxConnection {
#Test
public void testLinux() throws Exception{
LinuxConnection obj = new LinuxConnection();
String command = "touch tester1.txt; sudo su -; rm tester1.txt;";
obj.createUpdateTBX2FileData(command);
}
}
Again i have spent hours on google trying to find a solution but was unsuccessful
Any help is appreciated
You are code is missing the rest of the code needed for this to run. You need to initialize the type of channel you need out of the initialized session object. Since you need to be able to run more than one command after each other, you need a Shell type channel:
You should check JSch's examples (i.e. Shell.java), here it is for a quick reference:
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/**
* This program enables you to connect to sshd server and get the shell prompt.
* $ CLASSPATH=.:../build javac Shell.java
* $ CLASSPATH=.:../build java Shell
* You will be asked username, hostname and passwd.
* If everything works fine, you will get the shell prompt. Output will
* be ugly because of lacks of terminal-emulation, but you can issue commands.
*
*/
import com.jcraft.jsch.*;
import java.awt.*;
import javax.swing.*;
public class Shell{
public static void main(String[] arg){
try{
JSch jsch=new JSch();
//jsch.setKnownHosts("/home/foo/.ssh/known_hosts");
String host=null;
if(arg.length>0){
host=arg[0];
}
else{
host=JOptionPane.showInputDialog("Enter username#hostname",
System.getProperty("user.name")+
"#localhost");
}
String user=host.substring(0, host.indexOf('#'));
host=host.substring(host.indexOf('#')+1);
Session session=jsch.getSession(user, host, 22);
String passwd = JOptionPane.showInputDialog("Enter password");
session.setPassword(passwd);
UserInfo ui = new MyUserInfo(){
public void showMessage(String message){
JOptionPane.showMessageDialog(null, message);
}
public boolean promptYesNo(String message){
Object[] options={ "yes", "no" };
int foo=JOptionPane.showOptionDialog(null,
message,
"Warning",
JOptionPane.DEFAULT_OPTION,
JOptionPane.WARNING_MESSAGE,
null, options, options[0]);
return foo==0;
}
// If password is not given before the invocation of Session#connect(),
// implement also following methods,
// * UserInfo#getPassword(),
// * UserInfo#promptPassword(String message) and
// * UIKeyboardInteractive#promptKeyboardInteractive()
};
session.setUserInfo(ui);
// It must not be recommended, but if you want to skip host-key check,
// invoke following,
// session.setConfig("StrictHostKeyChecking", "no");
//session.connect();
session.connect(30000); // making a connection with timeout.
Channel channel=session.openChannel("shell");
// Enable agent-forwarding.
//((ChannelShell)channel).setAgentForwarding(true);
channel.setInputStream(System.in);
/*
// a hack for MS-DOS prompt on Windows.
channel.setInputStream(new FilterInputStream(System.in){
public int read(byte[] b, int off, int len)throws IOException{
return in.read(b, off, (len>1024?1024:len));
}
});
*/
channel.setOutputStream(System.out);
/*
// Choose the pty-type "vt102".
((ChannelShell)channel).setPtyType("vt102");
*/
/*
// Set environment variable "LANG" as "ja_JP.eucJP".
((ChannelShell)channel).setEnv("LANG", "ja_JP.eucJP");
*/
//channel.connect();
channel.connect(3*1000);
}
catch(Exception e){
System.out.println(e);
}
}
public static abstract class MyUserInfo
implements UserInfo, UIKeyboardInteractive{
public String getPassword(){ return null; }
public boolean promptYesNo(String str){ return false; }
public String getPassphrase(){ return null; }
public boolean promptPassphrase(String message){ return false; }
public boolean promptPassword(String message){ return false; }
public void showMessage(String message){ }
public String[] promptKeyboardInteractive(String destination,
String name,
String instruction,
String[] prompt,
boolean[] echo){
return null;
}
}
}
Using jsch
when i run the following cmd 'sudo su -' the program hangs
[TestNG] Running:
C:\Users\brian.crosby\AppData\Local\Temp\testng-eclipse-952620154\testng-customsuite.xml
[root#tbx2-toy-1 ~]#
It looks like the "sudo su -" worked becasue the output states "[root#tbx2-toy-1 ~]#" but when i send it another cmd it is unresponsive.
heres the code:
package com.linux;
import java.io.InputStream;
import org.testng.annotations.*;
import com.jcraft.jsch.*;
import com.thoughtworks.selenium.*;
public class LinuxConnection extends SeleneseTestBase{
String host = null;
private StringBuilder strFileData;
String randomFileName = null;
public String getFileData() {
return strFileData.toString();
}
public String getRandomFileName() {
return randomFileName;
}
public LinuxConnection() {
strFileData = new StringBuilder();
}
#Test
public void createUpdateTBX2FileData(String command)throws Exception {
try {
JSch jsch = new JSch();
host = "brian-crosby#************.net";
String user = host.substring(0, host.indexOf('#'));
host = host.substring(host.indexOf('#') + 1);
Session session = jsch.getSession(user, host, 22);
UserInfo ui = new MyUserInfo();
session.setUserInfo(ui);
session.connect();
ChannelExec channel = (ChannelExec)session.openChannel("exec");
((ChannelExec)channel).setPty(true);
((ChannelExec) channel).setCommand(command);
((ChannelExec) channel).setErrStream(System.err);
InputStream in = channel.getInputStream();
channel.connect();
byte[] tmp = new byte[2048];
while (in.read(tmp, 0, 2048) > 0) {
String str = new String(tmp);
strFileData.append(str);
System.out.println(strFileData);
}
in.close();
channel.disconnect();
session.disconnect();
} catch (Exception e) {
System.out.println(e);
}
}
public static class MyUserInfo implements UserInfo {
public String getPassword() {
return "********";
}
public boolean promptYesNo(String str) {
str = "Yes";
return true;
}
String passwd;
public String getPassphrase() {
return null;
}
public boolean promptPassphrase(String message) {
return true;
}
public boolean promptPassword(String message) {
passwd = "*******";
return true;
}
public void showMessage(String message) {
}
}
}
Here is where i am sending the cmds:
package com.linux;
import org.testng.annotations.*;
public class testLinuxConnection {
#Test
public void testLinux() throws Exception{
LinuxConnection obj = new LinuxConnection();
String command = "touch tester1.txt; sudo su -; rm tester1.txt;";
obj.createUpdateTBX2FileData(command);
}
}
Again i have spent hours on google trying to find a solution but was unsuccessful
Any help is appreciated
You are code is missing the rest of the code needed for this to run. You need to initialize the type of channel you need out of the initialized session object. Since you need to be able to run more than one command after each other, you need a Shell type channel:
You should check JSch's examples (i.e. Shell.java), here it is for a quick reference:
/* -*-mode:java; c-basic-offset:2; indent-tabs-mode:nil -*- */
/**
* This program enables you to connect to sshd server and get the shell prompt.
* $ CLASSPATH=.:../build javac Shell.java
* $ CLASSPATH=.:../build java Shell
* You will be asked username, hostname and passwd.
* If everything works fine, you will get the shell prompt. Output will
* be ugly because of lacks of terminal-emulation, but you can issue commands.
*
*/
import com.jcraft.jsch.*;
import java.awt.*;
import javax.swing.*;
public class Shell{
public static void main(String[] arg){
try{
JSch jsch=new JSch();
//jsch.setKnownHosts("/home/foo/.ssh/known_hosts");
String host=null;
if(arg.length>0){
host=arg[0];
}
else{
host=JOptionPane.showInputDialog("Enter username#hostname",
System.getProperty("user.name")+
"#localhost");
}
String user=host.substring(0, host.indexOf('#'));
host=host.substring(host.indexOf('#')+1);
Session session=jsch.getSession(user, host, 22);
String passwd = JOptionPane.showInputDialog("Enter password");
session.setPassword(passwd);
UserInfo ui = new MyUserInfo(){
public void showMessage(String message){
JOptionPane.showMessageDialog(null, message);
}
public boolean promptYesNo(String message){
Object[] options={ "yes", "no" };
int foo=JOptionPane.showOptionDialog(null,
message,
"Warning",
JOptionPane.DEFAULT_OPTION,
JOptionPane.WARNING_MESSAGE,
null, options, options[0]);
return foo==0;
}
// If password is not given before the invocation of Session#connect(),
// implement also following methods,
// * UserInfo#getPassword(),
// * UserInfo#promptPassword(String message) and
// * UIKeyboardInteractive#promptKeyboardInteractive()
};
session.setUserInfo(ui);
// It must not be recommended, but if you want to skip host-key check,
// invoke following,
// session.setConfig("StrictHostKeyChecking", "no");
//session.connect();
session.connect(30000); // making a connection with timeout.
Channel channel=session.openChannel("shell");
// Enable agent-forwarding.
//((ChannelShell)channel).setAgentForwarding(true);
channel.setInputStream(System.in);
/*
// a hack for MS-DOS prompt on Windows.
channel.setInputStream(new FilterInputStream(System.in){
public int read(byte[] b, int off, int len)throws IOException{
return in.read(b, off, (len>1024?1024:len));
}
});
*/
channel.setOutputStream(System.out);
/*
// Choose the pty-type "vt102".
((ChannelShell)channel).setPtyType("vt102");
*/
/*
// Set environment variable "LANG" as "ja_JP.eucJP".
((ChannelShell)channel).setEnv("LANG", "ja_JP.eucJP");
*/
//channel.connect();
channel.connect(3*1000);
}
catch(Exception e){
System.out.println(e);
}
}
public static abstract class MyUserInfo
implements UserInfo, UIKeyboardInteractive{
public String getPassword(){ return null; }
public boolean promptYesNo(String str){ return false; }
public String getPassphrase(){ return null; }
public boolean promptPassphrase(String message){ return false; }
public boolean promptPassword(String message){ return false; }
public void showMessage(String message){ }
public String[] promptKeyboardInteractive(String destination,
String name,
String instruction,
String[] prompt,
boolean[] echo){
return null;
}
}
}
I have this simple code to perdiodically access a pop3 server and check if there are new messages in the inbox folder
public static void main(String[] args) {
try {
String storeType = "pop3";
String host = "...";
int port = ...;
String user = "...";
String psw = "...";
//
int delay = 1;
long mins = 200 * 60 * delay;
firstAccess = true;
Properties properties = new Properties();
properties.put("mail.pop3.host", host);
properties.put("mail.pop3.user", user);
properties.put("mail.pop3.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
properties.put("mail.pop3.port", port);
RomasAuthenticator r = new RomasAuthenticator(user, psw);
Session session = Session.getDefaultInstance(properties, r);
POP3Store emailStore = (POP3Store) session.getStore(storeType);
emailStore.connect(host, port, user, psw);
Folder emailFolder = emailStore.getFolder("INBOX");
emailFolder.open(Folder.READ_ONLY);
while (true) {
if (checkInbox(emailFolder)) {
//prepara la notifica per il voice_service
System.out.println("mes!");
}
firstAccess = false;
Thread.sleep(mins);
}
} catch (Exception ex) {
//return null;
}
}
private static boolean checkInbox(Folder inbox_folder) throws MessagingException, IOException {
System.out.println("checking");
boolean res = false;
try {
int email_actual_count = inbox_folder.getMessageCount();
if (email_actual_count > email_prev_count /*or hasNewMessages()*/) {
if (!firstAccess) {
res = true;
}
}
//bisogna aggiornare comunque email_count in caso siano stati cancellati messaggi
email_prev_count = email_actual_count;
}
catch (Exception e) {
e.printStackTrace();
}
return res;
}
Both getMessageCount() and hasNewMessages() do not work, because the first always returns the same number of messages, and the second always returns false. What's that I'm doing wrong?
I don't want to use a messagelistener because this code will run on a robot with really low performances..
thanks everyone
The JavaMail FAQ explains why these features don't work with the POP3 protocol.