Write to a windows network share from unix - java

The following code works like a charm in eclipse under windows:
public static void main(String[] args)
{
try
{
String filePath = "\\\\myserver\\dir";
String fileName = "myFile.txt";
FileWriter myFileWriter = new FileWriter(filePath + File.separator + fileName);
BufferedWriter myBufferedWriter = new BufferedWriter(myFileWriter);
myBufferedWriter.write("test");
myBufferedWriter.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
Now I want to run this code from a unix machine in the same network. The program runs, but does not write my file or throws an exception. Any ides ?
Cheers

If that destination unix machine has Samba installed you might want to try the following library:
http://jcifs.samba.org/
You would need a username and password though.
try {
String filePath = "myserver/dir";
String fileName = "myFile.txt";
String user = "username";
String password = "password";
// URL: smb://user:passwd#host/share/filname
SmbFileOutputStream out = new SmbFileOutputStream("smb://" + user + ":" + password + "#" + filePath
+ File.separator + fileName);
out.write("test".getBytes());
out.close();
} catch (Exception e) {
e.printStackTrace();
}
This would also work with a windows machine as the destination if the server is configured as an SMB server.

Because in Unix/Linux this is not the right path
String filePath = "\\\\myserver\\dir";
I suggest to check such path exist, and 99% chances you will not have permission to create them. It would be more or less
String filePath = "/usr/xx/";
Creating folder:
File temp = new File("temp");
boolean test = temp.mkDir();

Related

Apache commons NET FTP retrieve not working after file reading

I'm trying to make a launcher for my Java desktop application (separated applications), which has to look for an updated version of the main application on the server. My idea is to store the app version inside of a text file on each side.
I found (thanks to Google san) the way to read the version from the text file and download the jar directory with all of it's content (both on server side). I'm using the Apache Commons Net FTP library btw.
The problem comes when I try to download the jar directory from the server after beeing reading the text file. I get the text file content correctly, the files download fails though.
If I switch code lines to download the stuff first and then read the text file, both of them works well, but we all know that's not the way an update check should be.
I've been looking and I don't get what I'm doing wrong. It's my first time working with this library.
This is the code I'm working with:
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import org.apache.commons.io.IOUtils;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
class FTPUtil{
private String server = "www.server.host";
private int port = 21;
private String user = "user";
private String pass = "password";
private FTPClient ftpClient = new FTPClient();
public void Connect() throws IOException{
ftpClient.connect(server, port);
ftpClient.login(user, pass);
ftpClient.enterLocalPassiveMode();
System.out.println("Connected");
}
public void Disconnect() throws IOException{
ftpClient.logout();
ftpClient.disconnect();
System.out.println("Disconnected");
}
public double getServerVersion(String remoteDirPath) throws IOException{
InputStream inputStream = ftpClient.retrieveFileStream(remoteDirPath + "/version.txt");
return Double.parseDouble(IOUtils.toString(inputStream, "UTF-8"));
}
public boolean downloadSingleFile(String remoteFilePath, String savePath) throws IOException{
File downloadFile = new File(savePath);
File parentDir = downloadFile.getParentFile();
if(!parentDir.exists())
parentDir.mkdir();
OutputStream outputStream = new BufferedOutputStream(new FileOutputStream(downloadFile));
try{
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
return ftpClient.retrieveFile(remoteFilePath, outputStream);
}catch(IOException e){
throw e;
}finally{
if(outputStream != null)
outputStream.close();
}
}
public void downloadDirectory(String parentDir, String currentDir, String saveDir) throws IOException{
String dirToList = parentDir;
if(!currentDir.equals(""))
dirToList += "/" + currentDir;
FTPFile[] subFiles = ftpClient.listFiles(dirToList);
if(subFiles != null && subFiles.length > 0){
for(FTPFile aFile : subFiles){
String currentFileName = aFile.getName();
// skip parent directory and the directory itself
if(currentFileName.equals(".") || currentFileName.equals(".."))
continue;
String filePath = parentDir + "/" + currentDir + "/" + currentFileName;
if(currentDir.equals(""))
filePath = parentDir + "/" + currentFileName;
String newDirPath = saveDir + parentDir + File.separator + currentDir + File.separator + currentFileName;
if(currentDir.equals(""))
newDirPath = saveDir + parentDir + File.separator + currentFileName;
if(aFile.isDirectory()){
// create the directory in saveDir
File newDir = new File(newDirPath);
boolean created = newDir.mkdirs();
if(created)
System.out.println("CREATED the directory: " + newDirPath);
else
System.out.println("COULD NOT create the directory: " + newDirPath);
// download the sub directory
downloadDirectory(dirToList, currentFileName, saveDir);
}else{
// download the file
boolean success = downloadSingleFile(filePath, newDirPath);
if(success)
System.out.println("DOWNLOADED the file: " + filePath);
else
System.out.println("COULD NOT download the file: " + filePath);
}
}
}
}
}
import java.io.IOException;
public class Main{
public static void main(String[] args){
String project = "ServerFolderName";
String remoteDirPath = "/" + project;
String saveDirPath = "C:/Users/username/Desktop";
FTPUtil ob = new FTPUtil();
try{
ob.Connect();
System.out.println(ob.getServerVersion(remoteDirPath));
ob.downloadDirectory(remoteDirPath, "", saveDirPath);
ob.Disconnect();
}catch(IOException e){
e.printStackTrace();
}
}
}
And the console output:
run:
Connected
1.0
Exception in thread "main" org.apache.commons.net.ftp.parser.ParserInitializationException: Unknown parser type: 0.000 seconds (measured here), 37.12 Kbytes per second
at org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory.createFileEntryParser(DefaultFTPFileEntryParserFactory.java:170)
at org.apache.commons.net.ftp.parser.DefaultFTPFileEntryParserFactory.createFileEntryParser(DefaultFTPFileEntryParserFactory.java:94)
at org.apache.commons.net.ftp.FTPClient.__createParser(FTPClient.java:3381)
at org.apache.commons.net.ftp.FTPClient.initiateListParsing(FTPClient.java:3338)
at org.apache.commons.net.ftp.FTPClient.listFiles(FTPClient.java:3016)
at generateupdateinfo.FTPUtil.downloadDirectory(FTPUtil.java:58)
at generateupdateinfo.Main.main(Main.java:13)
C:\Users\username\AppData\Local\NetBeans\Cache\8.2\executor-snippets\run.xml:53: Java returned: 1
BUILD FAILED (total time: 0 seconds)
Maybe I'm going the wrong way doing this launcher/updater, I'm open to suggestions and new ideas to achieve it.
Edit:
I noticed that it works if I renew the server connection with Disconnect() and Connect() after reading the text file and before downloading the files. I still feel should be another way, doesn't look quite good.
ob.Connect();
System.out.println(ob.getServerVersion(remoteDirPath));
ob.Disconnect();
ob.Connect();
ob.downloadDirectory(remoteDirPath, "", saveDirPath);
ob.Disconnect();
I found the problem. Apparently I just have to flush the server replies with ftpClient.completePendingCommand() after reading the version from the text file. I still do not get why happens just with one of both processes though, I would like to understand.
Thanks!:)

SFTP file transfer using Apache Commons Vfs2

I am using Apache Commons VFS2 to upload a file to server. Below is the code for the same. I have all the credentials right. The code printed "File uploaded successfully" String as well. But, I could not find the file on server when i cross checked it. Is there anything i am missing here in the code ?
I have all the Jars required (Apache Commons VFS jars, JSH jar)
public static void main(String[] args) {
SendMyFiles sendMyFiles = new SendMyFiles();
sendMyFiles.startFTP("C:/useragent.log");
}
public boolean startFTP(String fileToFTP) {
props = new Properties();
StandardFileSystemManager manager = new StandardFileSystemManager();
try {
// props.load(new FileInputStream("properties/" +
// propertiesFilename));
String serverAddress = "10.111.111.11";
String userId = "username";
String password = "password";
String remoteDirectory = "local/home/client/files/";
// check if the file exists
String filepath = fileToFTP;
File file = new File(filepath);
if (!file.exists())
throw new RuntimeException("Error. Local file not found");
// Initializes the file manager
manager.init();
// Setup our SFTP configuration
FileSystemOptions opts = new FileSystemOptions();
SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(opts, "no");
SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, true);
SftpFileSystemConfigBuilder.getInstance().setTimeout(opts, 10000);
// Create the SFTP URI using the host name, userid, password, remote
// path and file name
String sftpUri = "sftp://" + userId + ":" + password + "#" + serverAddress + "/" + remoteDirectory;
// Create local file object
FileObject localFile = manager.resolveFile(file.getAbsolutePath());
// Create remote file object
FileObject remoteFile = manager.resolveFile(sftpUri, opts);
// Copy local file to sftp server
remoteFile.copyFrom(localFile, Selectors.SELECT_SELF);
System.out.println("File upload successful");
} catch (Exception ex) {
ex.printStackTrace();
return false;
} finally {
manager.close();
}
return true;
}
I'd assume that the sftpUri should be a path to the destination file, not directory:
String sftpUri =
"sftp://" + userId + ":" + password + "#" + serverAddress + "/" + remoteDirectory + "/" +
file.getName();

Getting current jar file's name

I have this code which on the dev-environment return the information.
But when I run from the jar the code doesn't follow how it should.
The name of the jar is hardcoded and would like to get it's name, because versions vary.
private static String getManifestUrlForClass(Class<?> cl) throws URISyntaxException, IOException {
URL url = cl.getResource(cl.getSimpleName() + ".class");
String s = url.toString();
System.out.println("URL Path: " + url.getPath());
System.out.println("URL File: " + url.getFile());
String path = MYCLASS.class.getProtectionDomain().getCodeSource().getLocation().getPath();
String revisionNumber = "";
String decodedPath = "";
JarFile jarfile = null;
try {
decodedPath = URLDecoder.decode(path, "UTF-8").replace("classes", "");
try {
jarfile = new JarFile(decodedPath + "MYJAR-ver.si.on.jar");
} catch (IOException e1) {
System.out.println("or Path to file cannot decode...");
e1.printStackTrace();
}
Manifest manifestFromJar = jarfile.getManifest(); //
System.out.println("Manifest from " + jarfile.getName().toString() + " = "
+ manifestFromJar.getMainAttributes().getValue("Revision-Number").toString());
revisionNumber = manifestFromJar.getMainAttributes().getValue("Revision-Number").toString();
} catch (IOException e) {
System.out.println(url.getFile().toString() + "is not jar");// TODO Auto-generated catch block
System.out.println("or Path to file cannot decode...");
e.printStackTrace();
}
return revisionNumber;
}
MYJAR will always be the same but the |ver.si.on| will most likely vary and hardcoding the name isn't a best practice.
What I want to do?
1. Get the MYJAR-ver.si.on.jar's location no matter where it is located
2. Use the location to access it's Manifest
3. Use the Manifest to extract revision number
4. Show the revision number in the ui
I'm new yet to java and don't understand it pretty well. I've read something about using "rsrc:" to get to the jar, or something similar to this https://stackoverflow.com/a/40680501/6756124 .

Running multiple Batch files from different threads Java

I have n number of thread getting created at run time according to the input source files present in a folder. For every thread, I have one common class which has all the functions present that are used by every thread. Every thing is working perfectly except the part where batch files are run.
I have main class which is creating thread(which is working perfectly fine). Then I am creating batch files with relevant contents( which is also running perfectly). After that, only 1(can be anyone, no specific pattern) thread is able to execute the batch file and not the others.
Code:
String batch_content = "echo off \n "
+ "powershell.exe -file "
+ utility_path + "convertCSVSwiss.ps1 " + fpath + filename + " -executionpolicy Unrestricted \n ";
String batch_name = "batch_" + fname +"_"+sdf.format(cal.getTime())+ ".bat";
Utils.createBatchFile(batch_content, bat_file_path, batch_name);
Utils.RunBatch(bat_file_path, batch_name,csv_file_path,fname);
Utils.createBatchFile is working fine which create a batch file with the batch content. But Utils.RunBatch seems to having some problem. Here is the code for RunBatch:
public static void RunBatch(String filepath, String filename,String csv_file_path,String fname) throws Exception {
try {
System.out.println("Started Program");
new File(csv_file_path + "\\" + fname).mkdir();
String filePath1 = filepath + filename;
System.out.println("Batch file running is " + filePath1);
Process p = Runtime.getRuntime().exec(new String[] { "cmd.exe", "/c", filePath1 });
p.getOutputStream().close();
p.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
}
My log file prints this:
Batch file running is C:\ER\ETL\bat files\batch_Sample_Data_10_40_16_12_40_37.bat
Batch file running is C:\ER\ETL\bat files\batch_ssd_10_40_16_12_40_37.bat
but it runs only the first one.
Any help would be appreciated.
P.S I am sorry if I missed any information that may be necessary to get this problem resolved. Please let me know and I can then edit my post.
EDIT:
Here is my code.
//main class to start new thread for every excel file present in the source directory
public class LoadData{
public static void main(String[] args) throws Exception{
try{
File folder = new File(fpath);
File[] listoffiles = folder.listFiles();
for (int i = 0; i < listoffiles.length; i++) {
if (listoffiles[i].isFile()) {
filename = listoffiles[i].getName();
c = filename.lastIndexOf(".");
absfilename = filename.substring(0, c);
System.out.println("File name with extension is "+filename);
System.out.println("File name is "+absfilename);
System.out.println("Starting thread for "+absfilename);
ConvertToCSV et = new ConvertToCSV();
et.fpath = fpath;
et.utility_path=utility_path;
et.filename=filename;
et.fname = absfilename;
et.bat_file_path =bat_file_path;
et.tpath =tpath;
et.csv_file_path=csv_file_path;
Thread t = new Thread(et);
t.start();
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
}
//class to create the batch file content
public class ConvertToCSV implements Runnable{
String fpath,utility_path,filename,fname,bat_file_path,tpath,csv_file_path;
try{
String batch_content = "echo off \n "
+ "powershell.exe -file "
+ path_to_powershell_script_to_convert_excel_into_csv + "convertCSVSwiss.ps1 " + path_and_name_to_the_excel_file " -executionpolicy Unrestricted \n ";
String batch_name = "batch_" + excel_file_name +"_"+sdf.format(cal.getTime())+ ".bat";
Utils.createBatchFile(batch_content, bat_file_path, batch_name);
Utils.RunBatch(bat_file_path, batch_name,csv_file_path,fname);
}
catch (Exception e) {
e.printStackTrace();
}
}
public class Utils{
//function to create the batch file
public static void createBatchFile(String batch_content, String path, String batch_name) throws IOException {
String p = path + batch_name;
File batfile = new File(p);
FileWriter fw = new FileWriter(batfile);
fw.write(batch_content);
fw.close();
}
//function to run the batch file
public static void RunBatch(String filepath, String filename,String csv_file_path,String fname) throws Exception {
try {
System.out.println("Started Program");
new File(csv_file_path + "\\" + fname).mkdir();
String filePath1 = filepath + filename;
System.out.println("Batch file running is " + filePath1);
Process p = Runtime.getRuntime().exec(new String[] { "cmd.exe", "/c", filePath1 });
p.getOutputStream().close();
p.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
}
}
EDIT2: I have added the run for ConvertTO CSV. My code is doing say 10 things, and 9 of them are working fine except running two batch files with different names from the same folder
public class ConvertToCSV implements Runnable{
String fpath,utility_path,filename,fname,bat_file_path,tpath,csv_file_path,pg_db_url,pg_db,pg_db_uid,pg_db_pwd,plpgsql_path,Log_Path;
SimpleDateFormat sdf = new SimpleDateFormat("dd_mm_yy_hh_mm_ss");
Calendar cal = Calendar.getInstance();
#Override
public void run() {
try {
runConvertToCSV(fpath,utility_path,filename,fname,bat_file_path,tpath,csv_file_path,plpgsql_path);
} catch (Exception e) {
e.printStackTrace();
}
}
private void runConvertToCSV(String fpath,String utility_path,String filename,String fname,String bat_file,String tpath,String csv_file_path,String plpgsql_path) throws Exception{try{
String batch_content = "echo off \n "
+ "powershell.exe -file "
+ path_to_powershell_script_to_convert_excel_into_csv + "convertCSVSwiss.ps1 " + path_and_name_to_the_excel_file " -executionpolicy Unrestricted \n ";
String batch_name = "batch_" + excel_file_name +"_"+sdf.format(cal.getTime())+ ".bat";
Utils.createBatchFile(batch_content, bat_file_path, batch_name);
Utils.RunBatch(bat_file_path, batch_name,csv_file_path,fname);
}
catch (Exception e) {
e.printStackTrace();
}
}
EDIT3#:
My guess was that maybe because all the batch files are trying to access the same powershell script, that is why it is not working. But then i created ps script for every batch file. Also, added error stream to the stdout to check if there is any error and this is what i am getting:
Standard Error:
The RPC server is unavailable. (Exception from HRESULT: 0x800706BA)
At C:\ER\ETL\ETL_SOURCE\convertCSVSwiss_Swiss_Sample_Data.ps1:24 char:2
+ $Worksheet.SaveAs($ExtractedFileName,6)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [], COMException
+ FullyQualifiedErrorId : System.Runtime.InteropServices.COMException
there are number of same error at different line. NOTE: It is the same ps script for all the batch files, it runs only for one and not for others. and that one can be anyone(no pattern).
If i run the above batch file manually, then it succeeds.

connect to an IP address true a file sharing program

I have this file sharing program, where i can get mye files from a local location JFileChooser chooser = new JFileChooser("C://Users"), but i want to get files from a Server using an IP address. I have trying String hostname = "192.168.1.1"; but its not working. When i open the file chooser i get to my own folder. some tips?
public void download(String username) throws RemoteException, NullPointerException{
JFileChooser chooser = new JFileChooser("//" + hostname + "/C://");
chooser.setFileView(new FileView() {
#Override
public Boolean isTraversable(File f) {
return (f.isDirectory() && f.getName().equals("C://"));
}
});
int returnVal = chooser.showOpenDialog(parent);
if (returnVal == JFileChooser.APPROVE_OPTION) {
System.out.println("You chose to open this file: " + chooser.getSelectedFile().getName());
} try {
String fileName = chooser.getSelectedFile().getName();
File selectedFile = chooser.getSelectedFile();
//String name = "//" + hostname + "/chatter";
System.out.println(fileName);
//ChatFront cf = (ChatFront) Naming.lookup(name);
String ClientDirectory = getProperty + "/desktop/";
byte[] filedata = cf.downloadFile(selectedFile);
File file = new File(fileName);
BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(ClientDirectory + file.getName()));
output.write(filedata, 0, filedata.length);
notifySelf(getUsername(), "You have now downloaded: " + file.getName() + " from the server");
output.flush();
output.close();
} catch (Exception e) {
System.err.println("FileServer exception: " + e.getMessage());
e.printStackTrace();
}
}
Thanks in Advance :)
You're using "//" + hostname + "/C://" as the path for your JFileChooser. That's not a valid path. If you're trying to access files in a shared folder on a LAN, the path for that looks like \\hostname\sharename.
Even if no shared folders have been defined on the remote machine, may be an "administrative share" of the C: drive called C$, so you could use \\hostname\C$. But you have to authenticate as a valid user on that system to have permission to access the share. (I'm not sure how that'll work when you try to acccess the path from a Java program — Windows might pop up a login box for the remote system, or it might just fail.)

Categories

Resources