Unable to write to specified path in internal storage in android - java

I am trying to write to a specific path in internal storage in my android app :/data/somefolder
but I get the error java.io.filenotfoundexception : Permission denied
String testString="Hello World!";
File newFile=new File("/data/somefolder/testFile.txt");
try{
OutputStream myOut=new BufferedOutputStream(new FileOutputStream(newFile,true));
myOut.write(testString.getBytes());
myOut.flush();
myOut.close();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
My question is : Is it even possible to write into this folder in android internal storage or does android restrict file creation only to the specific package like
/data/data/package/files ?
I tried using FileOutputStream and the file got created successfully in /data/data/package/files.

I don't think you can just write into the data dir. That would require root access. You can either use the apps internal storage or the external storage (SD card). Please see here how that works.

Related

Why isn't my properties file updated in my Web App project?

I am trying to read and write a properties file with all my server and database connections in my JSF web application project in eclipse. Am using log4j to write to console. My config.properties file is:
dbserver=localhost
dbname=mydatabase;instance=myinstance
dbuser=myuser
dbpassword=mypassword
I placed my config.properties file in webapp/WEB-INF/classes folder (this is the classpath right?). I have verified that it is reading the file correctly in this specific location because if I delete the file, it breaks.
In my managed bean, I have functions to read and write to the config.properties file.
public void getSettings() {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
InputStream input = classLoader.getResourceAsStream("config.properties");
Properties properties = new Properties();
try {
properties.load(input);
this.server = properties.getProperty("dbserver");
this.db = properties.getProperty("dbname");
this.user = properties.getProperty("dbuser");
this.pass = properties.getProperty("dbpassword");
logger.info("Config file successfully loaded!");
} catch (IOException e) {
logger.error("Loading Database Settings Error with " + e);
} finally {
if (input != null) {
try {
input.close();
logger.info("Closing config file...");
} catch (IOException e) {
logger.error("Error closing config file with " + e);
}
}
}
}
public void saveSettings() {
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
Properties props = new Properties();
OutputStream out = null;
try {
props.setProperty("dbserver", this.server);
props.setProperty("dbname", this.db);
props.setProperty("dbuser", this.user);
props.setProperty("dbpassword", this.pass);
URL url = classLoader.getResource("config.properties");
File file = null;
try {
file = new File(url.toURI().getPath());
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// File f = new File("config.properties");
out = new FileOutputStream(file);
props.store(out, "This is an optional header comment string");
logger.info("Config file successfully saved!");
} catch (IOException io) {
logger.error("Saving configuration properties failed error with : " + io.getMessage());
} finally {
if (out != null) {
try {
logger.info("Closing config file...");
out.close();
} catch (IOException e) {
logger.error("Failed closing configuration properties file error with : " + e);
}
}
}
}
I never had an issue reading from the properties file but had a hard time writing to the file. This issue seemed to have been solved by specifying
URL url = classLoader.getResource("config.properties");
Now, if I change the server name from "localhost" to "192.168.1.1", I can see that the new information persists even though I refresh the page or restart the server. HOWEVER... when I open the config.properties file, I still see
dbserver=localhost
when I am expecting to see
dbserver=192.168.1.1
The information seems to persist somewhere else even though the file still remains the same? How and where can I access the contents of my properties fie to see the changes that are being made to it?
Modifying the WAR file is a bad idea (for example, some web servers may notice the file modification an redeploy your app, there may be problems when the server explodes the war on deployment etc.)
I would suggest applying an alternative approach - some possibilities are:
Place the properties in a database table, so they can be easily modified
Use an external properties file for overriding your "Property.prop" file settings. You can pull this off for example as follows. Assume that the default property values are bundled in your WAR and the modified values are saved to some other path, which is defined using a system property - let say it's called CONFIG_LOCATION. Now after loading your properties from the bundle you read them also from this external "overrides.prop" file - this overrides your defaults from "Property.prop":
PropertiesConfiguration pc1=new PropertiesConfiguration(a);
try(
FileReader propReader = new FileReader(System.getenv().get("CONFIG_FILES") +"/overrides.prop"){ pc1.load(propReader);
}
When you need to save changes, you do that to "overrides.prop" - this will save all the properties, not only the changed ones, but that should have no negative effects.

Permission denied for hive scratch directory while trying to establish connection using Hive streaming api

I am writing a sample program using HCatalogue Streaming api
I have a running hadoop, Hiveserver and a Hivemetastore server.
I write a java program to connect to hive metastore.The source code is given below
public class HCatalogueStreamingclient {
public static void main(String[] args) {
System.setProperty("hadoop.home.dir", "E:\\midhun\\hadoop\\hive\\winutils");
String dbName = "hive_streaming";
String tblName = "alerts";
ArrayList<String> partitionVals = new ArrayList<String>(2);
partitionVals.add("Asia");
partitionVals.add("India");
HiveEndPoint hiveEP = new HiveEndPoint("thrift://192.168.10.149:8000", dbName, tblName, partitionVals);
HiveConf conf = new HiveConf();
conf.set("hive.exec.scratchdir", "/tmp/hivetmp");
try {
StreamingConnection connection = hiveEP.newConnection(true,conf);
} catch (ConnectionError e) {
e.printStackTrace();
} catch (InvalidPartition e) {
e.printStackTrace();
} catch (InvalidTable e) {
e.printStackTrace();
} catch (PartitionCreationFailed e) {
e.printStackTrace();
} catch (ImpersonationFailed e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
While running the program I am getting following exception
Exception in thread "main" java.lang.RuntimeException: The root scratch dir: /tmp/hivetmp on HDFS should be writable. Current permissions are: rw-rw-rw-
at org.apache.hadoop.hive.ql.session.SessionState.createRootHDFSDir(SessionState.java:690)
at org.apache.hadoop.hive.ql.session.SessionState.createSessionDirs(SessionState.java:622)
at org.apache.hadoop.hive.ql.session.SessionState.start(SessionState.java:550)
at org.apache.hadoop.hive.ql.session.SessionState.start(SessionState.java:513)
at org.apache.hive.hcatalog.streaming.HiveEndPoint$ConnectionImpl.createPartitionIfNotExists(HiveEndPoint.java:445)
at org.apache.hive.hcatalog.streaming.HiveEndPoint$ConnectionImpl.<init>(HiveEndPoint.java:314)
at org.apache.hive.hcatalog.streaming.HiveEndPoint$ConnectionImpl.<init>(HiveEndPoint.java:278)
at org.apache.hive.hcatalog.streaming.HiveEndPoint.newConnectionImpl(HiveEndPoint.java:215)
at org.apache.hive.hcatalog.streaming.HiveEndPoint.newConnection(HiveEndPoint.java:192)
at org.apache.hive.hcatalog.streaming.HiveEndPoint.newConnection(HiveEndPoint.java:113)
at com.mj.HCatalogueStreamingclient.main(HCatalogueStreamingclient.java:27)
Any one have an Idea on how to grand write permission to the hdfs folder /tmp/hivetmp
The problem is identified.
We need to grand all permission for hadoop directory /tmp/hivetmp.The command for granding permission is $HADOOP_HOME/bin/hadoop fs -chmod 777 -R /tmp/hivetmp
I was running the program in Windows 7 64 bit OS.We need to download winutils appropriate to the operating system and version.
After doing above given points I was able to establish connection using Hive HCatalogue Streaming api

Open a downloaded JAR file Mac with Java code

I am creating a simple download program that opens a file with the web browser to download it. On Mac, there is a dialog when you open a downloaded executable JAR file that says you
can't open it because it is from an unidentified developer.
Is there a way to open the JAR file without the dialog by using Java code? Here is my code:
File newFile = new File(System.getProperty("user.home")+"/Library/AppTest/Application.jar");
File file = new File(System.getProperty("user.home")+"/Downloads/AppTest.jar");
try {
Files.move(file.toPath(), newFile.toPath());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
Desktop.getDesktop().open(file);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
The problem with the code is when it executes, it just shows this dialog, and will not let you open the file. I want to fix this without having to go to settings, because other users may have the same problem.
To open a JAR file on a mac, use Runtime:
String command = "java -jar path/to/jar/file";
Process p = Runtime.getRuntime().exec(command);
the above code is from this link.

Azure blob SAS and Localized file name

I am using jclouds APIs to upload files to azure blob but I could not find any way to generate SAS using jClouds APIs so using Azure APIs to create SAS for specific blob.
Problem I am facing is the file which i am trying to upload has localized characters in its name e.g. "Jérôme" which I have to encode and decode at specific level while uploading, I am making sure that at the time of SAS generation i am passing decoded(actual) name of file but I am not able to access the same using generated SAS.
PS. I have tried different combinations of encoding and decoding string(file name) in upload and SAS generation but all in vain.
Error I am getting is "No such blob exist" and in some case "signature validation failure"
can anyone guide me with appropriate approach for the same?
Please let me know in case code snippet is required.
UPLOAD:
try (BlobStoreContext context = ContextBuilder.newBuilder("azureblob")
.credentials(this.storeName, this.storeKey)
.buildView(BlobStoreContext.class)) {
final BlobStore store = context.getBlobStore();
payload.getContentMetadata().setContentLength(blobSize);
final Blob blob = store.blobBuilder(URLEncoder.encode(blobName, StorageConstants.UNICODE_FORMAT)).payload(payload).build();
logger.debug("Uploading...");
store.putBlob(this.containerName, blob);
logger.debug("Uploaded...");
return true;
} catch (IOException e) {
logger.error("IOException while uploading file to azure blob", e);
return false;
} catch (Exception e) {
logger.error("Exception while uploading file to azure blob", e);
return false;
}
SAS Generation
String url = "";
try
{
final CloudBlobContainer container = getUploadContainer();
final CloudBlockBlob blob = container.getBlockBlobReference(blobName);
url = blob.getUri() +"?"+ blob.generateSharedAccessSignature(getPolicy(), null);
} catch (StorageException e) {
logger.error("Storage Exception was encounter in generateAttachmentSasUrl() :", e);
} catch (InvalidKeyException e) {
logger.error("Invalid Key Exception was encountered in generateAttachmentSasUrl() :", e);
} catch (URISyntaxException e) {
logger.error("Problems creating an URI was encounter in generateAttachmentSasUrl() : ", e);
}
Please test with jclouds 2.0.0-SNAPSHOT. Many issues with URL encoding were fixed as part of JCLOUDS-217.

Android Mediaplayer Streaming - Worked now it doesn't

I have a strange problem. I have an mp3 stream I am trying to utilize within an application (2.1). Before you say streaming isn't supported here, it seems to be.
I was able to get it working last night by using the following code:
import java.io.IOException;
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
public class Stream extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
MediaPlayer mp = new MediaPlayer();
try {
mp.setDataSource("http://ipaddress:8000/");
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
mp.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mp.start();
}
}
However, today, it doesn't work. Furthermore, last night -- I was able to use the Internet Browser on my android phone to stream it. Although, last night when I went to the address, it opened the stream in video player. Nonetheless, I am unable to open it today in the browser, either.
In the browser, I keep getting the "page not displayed" page. I have actually verified it is online. I can browse to it from my PC (on the same network), and have confirmed internet connectivity to my android by utilizing other streaming applications and browsing to other web pages.
I am stumped as to why my code (or the stream) suddenly stopped working overnight on the phone. The code even works on a 2.1 emulator (and streams it).
Let me know what you all think, please.
Thanks in advance!
Seems to be a connectivity problem on the network side. Too many connections were opened from the phone on WiFi to the streaming server. This caused an IP blacklist. Today, this seems to have cleared up.

Categories

Resources