Trouble writing to file with SMBJ - java

Please help. I am unable to create and write to a file using SMBJ. I'm getting this error:
com.hierynomus.mssmb2.SMBApiException: STATUS_OBJECT_NAME_NOT_FOUND (0xc0000034): Create failed for <file path>
Is this a Windows errors or an SMBJ error? Am I using the SMBJ API correctly? I don't understand Windows file attributes/options well.
String fileName ="EricTestFile.txt";
String fileContents = "Mary had a little lamb.";
SMBClient client = new SMBClient();
try (Connection connection = client.connect(serverName)) {
AuthenticationContext ac = new AuthenticationContext(username, password.toCharArray(), domain);
Session session = connection.authenticate(ac);
// Connect to Share
try (DiskShare share = (DiskShare) session.connectShare(sharename)) {
for (FileIdBothDirectoryInformation f : share.list(folderName, "*.*")) {
System.out.println("File : " + f.getFileName());
}
//share.openFile(path, accessMask, attributes, shareAccesses, createDisposition, createOptions)
Set<FileAttributes> fileAttributes = new HashSet<>();
fileAttributes.add(FileAttributes.FILE_ATTRIBUTE_NORMAL);
Set<SMB2CreateOptions> createOptions = new HashSet<>();
createOptions.add(SMB2CreateOptions.FILE_RANDOM_ACCESS);
File f = share.openFile(folderName+"\\"+fileName, new HashSet(Arrays.asList(new AccessMask[]{AccessMask.GENERIC_ALL})), fileAttributes, SMB2ShareAccess.ALL, SMB2CreateDisposition.FILE_OVERWRITE, createOptions);
OutputStream oStream = f.getOutputStream();
oStream.write(fileContents.getBytes());
oStream.flush();
oStream.close();
}
} catch (IOException e) {
e.printStackTrace();
}

If the file that you're trying to open does not yet exist, you need to use a different SMB2CreateDisposition. You're now using FILE_OVERWRITE, which is documented as:
Overwrite the file if it already exists; otherwise, fail the operation. MUST NOT be used for a printer object.
You probably want to use FILE_OVERWRITE_IF, which does:
Overwrite the file if it already exists; otherwise, create the file. This value SHOULD NOT be used for a printer object.

Related

Updated property not shown in .properties using java

I am trying to store key and value pair in properties during server load. After saving, when i checked the .properties file, changes are not there. I am not sure what i missed out.
Not getting any exception or error. updated property changes is not reflected in my .properties file.
My resource file is in "src\main\resources\logintokencache.properties".
Properties prop = new Properties();
InputStream in = getClass().getClassLoader().getResourceAsStream("logintokencache.properties");
try {
prop.load(in);
prop.setProperty("key","value"); // Setting the property
// Tried using Filewriter to store the properties, not worked
File configFile = new File("logintokencache.properties");
FileWriter writer = new FileWriter(configFile);
prop.store(writer, null);
writer.close();
// Tried using FileOutputStream to store the properties, not worked
FileOutputStream output = new FileOutputStream("logintokencache.properties");
prop.store(output, "This is overwrite file");
// Reloaded the properties and also checked, not worked
prop.load(in);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
logintokencache.properties is stored at your working dir while the file you load is located somewhere at your classpath. So you are loading one file and store it to a different place.
If you are sure that the resource is writeable (that is not always be the case e.g. if it is insight a jar) you can access via
File f = new File(getClass().getClassLoader().getResource("logintokencache.properties").getFile());
FileOutputStream out = new FileOutputStream(f);
prop.store(out, "");

Reading/Writing to Properties Files inside the jar file

So i am getting back into writing Java after 4 years so please forgive any "rookie" mistakes.
I need to have a properties file where i can store some simple data for my application. The app data itself won't reside here but i will be storing info such as the file path to the last used data store, other settings, etc.
I managed to connect to the properties file which exists inside the same package as the class file attempting to connect to it and i can read the file but i am having trouble writing back to the file. I am pretty sure that my code works (at least it's not throwing any errors) but the change isn't reflected in the file itself after the app is run in Netbeans.
In the above image you can see the mainProperties.properties file in question and the class attempting to call it (prefManagement.java). So with that in mind here is my code to load the file:
Properties mainFile = new Properties();
try {
mainFile.load(prefManagement.class.getClass().getResourceAsStream("/numberAdditionUI/mainProperties.properties"));
} catch (IOException a) {
System.out.println("Couldn't find/load file!");
}
This works and i can check and confirm the one existing key (defaultXMLPath).
My code to add to this file is:
String confirmKey = "defaultXMLPath2";
String propKey = mainFile.getProperty(confirmKey);
if (propKey == null) {
// Key is not present so enter the key into the properties file
mainFile.setProperty(confirmKey, "testtest");
try{
FileOutputStream fos = new FileOutputStream("mainProperties.properties");
mainFile.store(fos, "testtest3");
fos.flush();
}catch(FileNotFoundException e ){
System.out.println("Couldn't find/load file3!");
}catch(IOException b){
System.out.println("Couldn't find/load file4!");
}
} else {
// Throw error saying key already exists
System.out.println("Key " + confirmKey + " already exists.");
}
As i mentioned above, everything runs without any errors and i can play around with trying to add the existing key and it throws the expected error. But when trying to add a new key/value pair it doesn't show up in the properties file afterwords. Why?
You should not be trying to write to "files" that exist inside of the jar file. Actually, technically, jar files don't hold files but rather they hold "resources", and for practical purposes, they are read-only. If you need to read and write to a properties file, it should be outside of the jar.
Your code writes to a local file mainProperties.properties the properties.
After you run your part of code, there you will find that a file mainProperties.properties has been created locally.
FileOutputStream fos = new FileOutputStream("mainProperties.properties");
Could order not to confuse the two files you specify the local file to another name. e.g. mainAppProp.properties .
Read the complete contents of the resource mainProperties.properties.
Write all the necessary properties to the local file mainAppProp.properties.
FileOutputStream fos = new FileOutputStream("mainAppProp.properties");
switch if file exists to your local file , if not create the file mainAppProp.properties and write all properties to it.
Test if file mainAppProp.properties exists locally.
Read the properties into a new "probs" variable.
Use only this file from now on.
Under no circumstances you can write the properties back into the .jar file.
Test it like
[...]
if (propKey == null) {
// Key is not present so enter the key into the properties file
mainFile.setProperty(confirmKey, "testtest");
[...]
Reader reader = null;
try
{
reader = new FileReader( "mainAppProp.properties" );
Properties prop2 = new Properties();
prop2.load( reader );
prop2.list( System.out );
}
catch ( IOException e )
{
e.printStackTrace();
}
finally
{
if (reader != null) {
reader.close();
}
}
}
[...]
}
output : with prop2.list( System.out );
-- listing properties --
defaultXMLPath2=testtest
content of the file mainAppProp.properties
#testtest3
#Mon Jul 14 14:33:20 BRT 2014
defaultXMLPath2=testtest
Challenge:
Read the Property file location in jar file
Read the Property file
Write the variable as system variables
public static void loadJarCongFile(Class Utilclass )
{
try{
String path= Utilclass.getResource("").getPath();
path=path.substring(6,path.length()-1);
path=path.split("!")[0];
System.out.println(path);
JarFile jarFile = new JarFile(path);
final Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) {
final JarEntry entry = entries.nextElement();
if (entry.getName().contains(".properties")) {
System.out.println("Jar File Property File: " + entry.getName());
JarEntry fileEntry = jarFile.getJarEntry(entry.getName());
InputStream input = jarFile.getInputStream(fileEntry);
setSystemvariable(input);
InputStreamReader isr = new InputStreamReader(input);
BufferedReader reader = new BufferedReader(isr);
String line;
while ((line = reader.readLine()) != null) {
System.out.println("Jar file"+line);
}
reader.close();
}
}
}
catch (Exception e)
{
System.out.println("Jar file reading Error");
}
}
public static void setSystemvariable(InputStream input)
{
Properties tmp1 = new Properties();
try {
tmp1.load(input);
for (Object element : tmp1.keySet()) {
System.setProperty(element.toString().trim(),
tmp1.getProperty(element.toString().trim()).trim());
}
} catch (IOException e) {
System.out.println("setSystemvariable method failure");
}
}

How to use values of build.properties in another property file using selenium webdriver

I am using eclipse for selenium webdriver. I have assigned an URL to the variable 'webdriver.url' in build.properties file. I have created another property file called 'ExpectedResults.properties'. I want to use the value of variable webdriver.url of build.properties in ExpectedResults.properties file. Is it possible to use. If possible can you please tell how it will be?
Thanks in advance.
Not clear whats the objective is. Two cases are possible here -
1.Assuming you have url in 'webdriver.url' variable.
You can write it to second property file ('ExpectedResults.properties') as
Properties prop = new Properties();
OutputStream output = null;
try {
output = new FileOutputStream("ExpectedResults.properties");
prop.setProperty("expected.url", webdriver.url);
prop.store(output, null);
} catch (IOException io) {
io.printStackTrace();
}
2 You can read both property files & compare URLs -
Properties prop = new Properties();
InputStream input = null;
try {
input = new FileInputStream("filename.properties");
prop.load(input);
System.out.println(prop.getProperty("webdriver.url"));
}
catch (IOException ex) {
ex.printStackTrace();
}

Properties setting via Servlet

I want to set data from configures.properties via servlet. configures.properties is locating in WEB-INF/classes. This is how I'm getting data:
public static String getDbPassword() {
Properties prop = new Properties();
try {
// load a properties file
InputStream in = Configures.class.getResourceAsStream(INPUT_FILE);
prop.load(in);
// get the property value
return prop.getProperty("dbPassword");
} catch (IOException ex) {
ex.printStackTrace();
}
return null;
}
But how to set? This is how I did:
public static void setDbPassword(String str) {
Properties prop = new Properties();
try {
//load a properties file
InputStream in = Configures.class.getResourceAsStream(INPUT_FILE);
prop.load(in);
prop.setProperty("dbPassword", str);
prop.store(new FileOutputStream(INPUT_FILE), null);
} catch (IOException ex) {
ex.printStackTrace();
}
}
But I'm catching java.io.FileNotFoundException after this. I think it happens after prop.store(new FileOutputStream(INPUT_FILE), null);. How should I modify OutputStream?
UPD:
This is how INPUT_FILE looks:
private static final String INPUT_FILE = "/config.properties";
Your INPUT_FILE is a resource path which getResourceAsStream will resolve relative to the classpath, but you're then trying to pass the same string to the FileOutputStream constructor which will try and treat it as an absolute path relative to the root of the filesystem. These are two different locations.
You could use ServletContext.getRealPath("WEB-INF/classes" + INPUT_FILE) to get the path you need for the FileOutputStream.
But the higher level issue here is that you shouldn't assume that your web application will have write access to its WEB-INF, or even that the directory exists on disk at all (e.g. if the app is running directly from a WAR rather than a directory unpacked on disk). If you want to store configuration data that can change then it should go in a file at a known location outside the web app (the location of this file could be an init parameter) where you know you will have read and write permission. This also stops your changes being overwritten when you deploy a new version of the app.
URL url = Configures.class.getResource(INPUT_FILE);
File file = new File(url.toURI());
OutputStream outputStream = new FileOutputStream(file);
...
prop.store(outputStream, null);
Try a FileWriter instead:
Writer writer = new FileWriter(INPUT_FILE);
...
prop.store(writer, null);
Can you try the following:
While reading the file
URL url = classLoader.getResource(INPUT_FILE);
InputStream in = url.openStream();
While writing :
new FileOutputStream(url.toURI().getPath())
Any files in your webapp should be considered read only. If you want mutable data you should use a database or some other data store.
J2EE advises against manipulating local files as it raises issues of clustering, transactions and security among other things.

How to load a properties file from the root directory?

I am currently loading a properties file like this:
private Properties loadProperties(String filename) throws IOException{
InputStream in = ClassLoader.getSystemResourceAsStream(filename);
if (in == null) {
throw new FileNotFoundException(filename + " file not found");
}
Properties props = new Properties();
props.load(in);
in.close();
return props;
}
However, at the moment my file lays at the scr\user.properties path.
But when I want to write to a properties file:
properties.setProperty(username, decryptMD5(password));
try {
properties.store(new FileOutputStream("user.properties"), null);
System.out.println("Wrote to propteries file!" + username + " " + password);
That piece of code generates me a new file at the root folder level of my project.
BUT I want to have one file to write\read.
Therefore how to do that?
PS.: When I want to specify the path I get "Not allowed to modify the file..."
The reason a new file is created because you are trying to create a new file when you are writing. You should first get handle to the user.properties that you want to write to as File object and then try to write to it.
The code would look something along the lines of
properties.setProperty(username, decryptMD5(password));
try{
//get the filename from url class
URL url = ClassLoader.getSystemResource("user.properties");
String fileName = url.getFile();
//write to the file
props.store(new FileWriter(fileName),null);
properties.store();
}catch(Exception e){
e.printStacktrace();
}

Categories