I am trying to create a Java Applet that outputs information to a text file located in the same directory as the java applet. I understand Java Applets are not ideal, but I have spent a great deal of time on this and if possible want to solve this through applets. Here is some of my code on how I could read code from a file into a text box. I assume it would be something similar to this, but outputted.
public void readFile() {
String line;
URL url = null;
try {
url = new URL(getCodeBase(), fileToRead);
}
catch(MalformedURLException e) {
}
try {
InputStream in = url.openStream();
BufferedReader bf = new BufferedReader
(new InputStreamReader(in));
strBuff = new StringBuffer();
while((line = bf.readLine()) != null){
strBuff.append(line + "\n");
}
a1.append("File Name : " + fileToRead + "\n");
a1.append(strBuff.toString());
}
catch(IOException e) {
e.printStackTrace();
}
}
If you want an applet to store data on the local machine, from 6u10 the javax.jnlp.PersistenceService is available.
or on your local machine...
java.io.File file = new java.io.File(System.getProperty("user.home"), "yourfile.txt");
You must have it signed, otherwise...
Keep in mind that from an Applet, you cannot directly write to the server's file system. You can issue a request to the server that causes the server to write to its own file system, but an Applet does not have a way to write to a file system on a remote machine.
A signed Applet has every right to write to the local file system of the person running the Applet. If you are writing to the "current directory" (rather than an absolute full path), then make sure you know what directory the Applet is running in. Otherwise you may indeed create a file, but not be able to find it!
EDIT
Signed Applet Tutorial
Related
Require to read a flat file that do not have any extension through URL, couldn't get this as browser(404) and java(FileNotFoundException) not taking the file as a resource to open.
import java.net.*;
import java.io.*;
public class URLTest {
public static void main(String[] args) {
/*Block 1: Reading a file "test.txt" (WITH extension) that works */
try{ System.out.println("Block 1");
URL url1 = new URL("http://localhost:8080/CtxPath/test.txt"); //file test.txt available at WebContent
BufferedReader in = new BufferedReader(new InputStreamReader(url1.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
} catch(Exception e) { e.printStackTrace(); }
/* Block 2 : Reading the other one "test" (WITHOUT extension) that throws Exception */
try{ System.out.println("Block 2");
URL url2 = new URL("http://localhost:8080/CtxPath/test"); ////file test also available at WebContent
BufferedReader in = new BufferedReader(new InputStreamReader(url2.openStream()));
String inputLine;
while ((inputLine = in.readLine()) != null)
System.out.println(inputLine);
in.close();
} catch(Exception e) { e.printStackTrace(); }
}
}
Output
Block 1
File content from test.txt read successfully.
Block 2
java.io.FileNotFoundException: http://localhost:8080/CtxPath/test
at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1624)
at java.net.URL.openStream(URL.java:1037)
at URLTest.main(URLTest.java:28)
Jboss 5.1 Java 1.7
Getting exception on open URL for the file(test) without extension. The other file with .txt extension(test.txt) that placed in the same location with similar content opens without any issues.
Is there any app specific or server specific config to do for allowing the file without extension to be served?
In the servlet container implementation, things without suffix "test" is not treat as file, but treat as servlet mapping.
You can download tomcat source code, the logic for this is similar in jboss, and take a look.
And I don't think you should make a file without suffix, if you really need to, then put it under WEB-INF/xxx/, then use a servlet to help read it.
Java is simply calling the URL. It cares not whether it has a . in the path. The server you are calling, on the other hand, /may/ have logic which determines how it attempts to fulfill the request. The FileNotFoundException indicates a 404 http status code was returned.
It may be possible that file does have extension that you may not be able to see because Operating system settings have hide the extensions or some rules on your server may causing it to return 404. Java does not give file not found exception because of extension.
Please let us know the issue, when you resolve it.
So what I am trying to achieve is reading the contents of a .txt file from a url:
BufferedReader reader = null;
File f = new File ("www.website.com/filename.txt");
if (f.exists()) {
try {
reader = new BufferedReader(new FileReader(f));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
String line = "";
try {
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
Even though I have content in the .txt file (only one line), when I print the line nothing shows up. Is reading a file from a URL or from your hard drive different, or am I doing something wrong?
The File class is for files on a "normal" file system (usually local, but potentially networked) - not URLs. Basically it's for the sort of file you can use (e.g. read or edit) directly on a command line, with no HTTP involved1.
That's what the URL class is for. So you can either use that (with URLConnection) or use a dedicated HTTP 3rd party library, such as the Apache HttpClient library.
1 I'm sure there are some shells which allow the use of URLs as if they were local filenames, but I'm talking about a more traditional approach.
I tried own my own and this worked...
URL urlObj=new URL("http://www.example.com/index.html"); //This can be any website' index.html or an available file
//we basically get HTML page/file
Scanner fGetter=new Scanner(urlObj.openStream());
while(fGetter.hasNext()){
System.out.println(""+fGetter.nextLine());
}
And I think "example.com" can be used without any legal issues :)
I don't actually know but I don't think you can read a file from a URL like that. You need to send a HTTP GET request to that url to read the information in.
See object HttpURLConnection.
http://docs.oracle.com/javase/7/docs/api/java/net/HttpURLConnection.html
I'm using the acm libraries for my Java program, and I want to embed my program into my website via HTML. I have other .jar files embedded just fine in my website, by using the
<applet archive="file.jar, acm.jar"
code="main.class"
width=400 height=600 />
but have found that when embedded in HTML the program sort of freaks out and stops responding when it gets to the part where it should load the .txt file.
I remember vaguely my AP CompSci teacher telling us that java in web browsers blocked the import of .txt files, but I might be remembering incorrectly. Here is my java code below:
public NameSurferDataBase(String filename) {
nameEntry = new HashMap<String, NameSurferEntry>();
try {
BufferedReader rd = new BufferedReader(new FileReader(filename));
while (true) {
String line = rd.readLine();
if (line == null) break;
NameSurferEntry entry = new NameSurferEntry(line);
nameEntry.put(entry.getName().toUpperCase(), entry);
}
} catch (IOException ex) {
throw new ErrorException(ex);
}
}
So not only do I not know how to actually add the .txt file as something to use before it runs, I don't even know if it is possible.
It's because when running applets, the security manager doesn't let you work with the filesystem (unless you specifically change the plugin settings which is a bad idea). If you're just trying to read, put the file in your classpath, and use ClassLoader.getResourceAsStream(String resource) to get the input stream instead.
I am working on an Android application that depends on an ELF binary:
our Java code interacts with this binary to get things done. This
runtime needs to be started and terminated on Application startup and
application exit / on demand.
Questions:
I am assuming that we will be able to execute this binary using the
Runtime.exec() API. Is there any constraints as to where I
need to be putting my library in the folder structure? How would the system runtime locate this executable? Is there some sort of class path setting?
Since the application has dependencies on this Runtime, I was
thinking of wrapping it around a service so that it can be started or
stopped as required. What is the best way to handle such executables
in Android project?
What are other alternatives, assuming that I do not have source code for this executable?
Please advice.
Thanks.
1) No, there should be no constrains, besides those that access system files and thus require root. The best place would be straight to /data/data/[your_package_name] to avoid polluting elsewhere.
2) A very thorough discussion about compiling against native libraries can be found here: http://www.aton.com/android-native-libraries-for-java-applications/ . Another option is a cross-compiler for arm (here is the one used to compile the kernel, it's free: http://www.codesourcery.com/sgpp/lite/arm ). If you plan to maintain a service that executes your cammand, be warned that services can be stopped and restarted by android at any moment.
3) Now, if you don't have the source code, I hope that your file is at least compiled as an arm executable. If not, I don't see how you could even run it.
You will execute the file by running the following commands in your java class:
String myExec = "/data/data/APPNAME/FILENAME";
Process process = Runtime.getRuntime().exec(myExec);
DataOutputStream os = new DataOutputStream(process.getOutputStream());
DataInputStream osRes = new DataInputStream(process.getInputStream());
I know nothing about your executable, so you may or may not need to actually get the inputStream and outputStream.
I am assuming that running adb to push the binary file is out of the question, so
I was looking for a neat way to package it. I found a great post about including an executable in your app. Check it out here:
http://gimite.net/en/index.php?Run%20native%20executable%20in%20Android%20App
The important part is this one (emphasis mine):
From Android Java app, using assets folder
Include the binary in the assets folder.
Use getAssets().open(FILENAME) to get an InputStream.
Write it to /data/data/APPNAME (e.g. /data/data/net.gimite.nativeexe), where your application has access to write files and make it executable.
Run /system/bin/chmod 744 /data/data/APPNAME/FILENAME using the code above.
Run your executable using the code above.
The post uses the assets folder, insted of the raw folder that android suggests for static files:
Tip: If you want to save a static file in your application at compile time, save the file in your project res/raw/ directory. You can open it with openRawResource(), passing the R.raw. resource ID. This method returns an InputStream that you can use to read the file (but you cannot write to the original file).
To access the data folder, you can follow the instructions here:
http://developer.android.com/guide/topics/data/data-storage.html#filesInternal
Also, there's the File#setExecutable(boolean); method that should works instead of the shell command.
So, putting everything together, I would try:
InputStream ins = context.getResources().openRawResource (R.raw.FILENAME)
byte[] buffer = new byte[ins.available()];
ins.read(buffer);
ins.close();
FileOutputStream fos = context.openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(buffer);
fos.close();
File file = context.getFileStreamPath (FILENAME);
file.setExecutable(true);
Of course, all this should be done only once after installation. You can have a quick check inside onCreate() or whatever that checks for the presence of the file and executes all this commands if the file is not there.
Let me know if it works. Good luck!
Here is a complete guide for how to package and run the executable. I based it on what I found here and other links, as well as my own trial and error.
1.) In your SDK project, put the executable file in your /assets folder
2.) Programmatically get the String of that files directory (/data/data/your_app_name/files) like this
String appFileDirectory = getFilesDir().getPath();
String executableFilePath = appFileDirectory + "/executable_file";
3.) In your app's project Java code: copy the executable file from /assets folder into your app's "files" subfolder (usually /data/data/your_app_name/files) with a function like this:
private void copyAssets(String filename) {
AssetManager assetManager = getAssets();
InputStream in = null;
OutputStream out = null;
Log.d(TAG, "Attempting to copy this file: " + filename); // + " to: " + assetCopyDestination);
try {
in = assetManager.open(filename);
Log.d(TAG, "outDir: " + appFileDirectory);
File outFile = new File(appFileDirectory, filename);
out = new FileOutputStream(outFile);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch(IOException e) {
Log.e(TAG, "Failed to copy asset file: " + filename, e);
}
Log.d(TAG, "Copy success: " + filename);
}
4.) Change the file permissions on executable_file to actually make it executable. Do it with Java calls:
File execFile = new File(executableFilePath);
execFile.setExecutable(true);
5.) Execute the file like this:
Process process = Runtime.getRuntime().exec(executableFilePath);
Note that any files referred to here (such as input and output files) must have their full path Strings constructed. This is because this is a separate spawned process and it has no concept of what the "pwd" is.
If you want to read the command's stdout you can do this, but so far it's only working for me for system commands (like "ls"), not the executable file:
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
int read;
char[] buffer = new char[4096];
StringBuffer output = new StringBuffer();
while ((read = reader.read(buffer)) > 0) {
output.append(buffer, 0, read);
}
reader.close();
process.waitFor();
Log.d(TAG, "output: " + output.toString());
For executing binary file starting from Android 10 it's only possible from read-only folder. It means that you should pack binary with your app. Android doc
Put android:extractNativeLibs="true" into AndroidManifest;
Put your binary to src/main/resources/lib/* directory, where * – stands for architecture of CPU, for instance armeabi-v7a;
Use code like this for executing:
private fun exec(command: String, params: String): String {
try {
val process = ProcessBuilder()
.directory(File(filesDir.parentFile!!, "lib"))
.command(command, params)
.redirectErrorStream(true)
.start()
val reader = BufferedReader(
InputStreamReader(process.inputStream)
)
val text = reader.readText()
reader.close()
process.waitFor()
return text
} catch (e: Exception) {
return e.message ?: "IOException"
}
}
Here is discussion with answer from android team on reddit.
I've done something like this using the NDK. My strategy was to recompile the program using the NDK and write some wrapper JNI code that called into the program's main function.
I'm not sure what the lifecycle of NDK code is like. Even services that are intended to be long-running can be started and stopped by the system when convenient. You would probably have to shutdown your NDK thread and restart it when necessary.
Basically my problem is a that I need to copy an uploaded file (which is placed in a temporary folder on my server providers Tomcat ie. not a local Tomcat).
The code I'm using works when I deploy my project on my local machine but stops working when I deploy it live.
I've found out that it has something to with my permissions in java.policy.
What I need to find out is how do I get access to the folder in which Tomcat stores the temporary file using Java.
When reading catalina.out this is the clue that the log gives me.
/usr/local/tomcat/work/Catalina/project name here/context of project here/upload_490341a6_12b1d397355_76ce_00000001.tmp
I'm thinking somewhere along the lines (note: this is not an actual method :P )
ServletActionContext.getContext().getSuperHiddenTemporaryCatalog();
The code snippet at the bottom has one flaw.
sourceFile and targetFile points to the same directory at the moment.
I want the sourceFile path to be the temporary tomcat-folder.
Thanks in advance! :D
public String saveImage(File file, String uploadedFileName) {
String path = ServletActionContext.getServletContext().getRealPath("images");
System.out.println(path);
String fullFileName = path + "/" + uploadedFileName;
System.out.println(fullFileName);
boolean successful = false;
try {
File sourceFile = new File(fullFileName);
File targetFile = new File(path + "/" + uploadedFileName);
InputStream in = new FileInputStream(sourceFile);
OutputStream out = new FileOutputStream(targetFile);
byte[] buf = new byte[1024];
int len;
while ((len = in.read(buf)) > 0) {
out.write(buf, 0, len);
}
in.close();
out.close();
} catch (Exception e) {
successful = false;
e.printStackTrace();
}
if (successful) {
return "context of project/images/" + uploadedFileName;
} else {
return "";
}
}
File tempDir = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
should give you access to your temporary directory in Tomcat. It would be strange if you could not at least read files from there.
The code I'm using works when I deploy my project on my local machine but stops working when I deploy it live. I've found out that it has something to with my permissions in java.policy.
Yes. This is an example of a Java security sandbox.
What I need to find out is how do I get access to the folder in which Tomcat stores the temporary file using Java.
You cannot circumvent the security sandbox (modulo some unpatched bug in your JVM). What you need to do is change the "java.policy" settings so that your webapp has permission copy the file to where it needs to be copied. You may need to discuss this with whoever has done the security design, etc for your production Tomcats.