I am trying to extract few files contained in the java project into a certain path, lets say "c:\temp".
I tried to use this example :
String home = getClass().getProtectionDomain().
getCodeSource().getLocation().toString().
substring(6);
JarFile jar = new JarFile(home);
ZipEntry entry = jar.getEntry("mydb.mdb");
File efile = new File(dest, entry.getName());
InputStream in =
new BufferedInputStream(jar.getInputStream(entry));
OutputStream out =
new BufferedOutputStream(new FileOutputStream(efile));
byte[] buffer = new byte[2048];
for (;;) {
int nBytes = in.read(buffer);
if (nBytes <= 0) break;
out.write(buffer, 0, nBytes);
}
out.flush();
out.close();
in.close();
I think I am doing it wrong and, this code probably looking for a specific jar but not in my project directory. I prefer to figure a way that can retrieve my files from resources package, inside the project folder and extract it to specific folder i choose.
I am using Eclipse, 1.4 J2SE library.
Well, it's hard to guess what's wrong without any code examples.
But as for pair of random guesses I could tell that sometimes you get this kind of error when the file is locked by earlier instance of your program which is still running. Make sure you've got only one running instance of Eclipse.
Also you can try to refresh the project folder by right click --> refresh to sync your file system with Eclipse's internal file system: when it comes to Eclipse, multiple refresh/rebuild someway magically solves project problems :)
Related
My project has the following directories in Java Web Netbeans.
I create a file and i want to save it inside the dist folder .
I tried using
FileOutputStream(".\\dist\\file.pdf"))
But i get can not locate path. If i use the whole path including '''C:// so on"" it works but it is not efficient if i specify it as the project would not be able to run in different machines.
What can I do for it ?
I don't know if it is the best way, but I did it in another project like this:
StringBuilder sb;
FileOutputStream fos;
sb = new StringBuilder("");
// to get project root:
sb.append(new java.io.File(".").getCanonicalPath());
// File.separator for system specific file separator:
sb.append(File.separator);
sb.append("dist");
sb.append(File.separator);
sb.append("file.pdf");
fos = new FileOutputStream(sb.toString());
As I said, I don't know if this is the best way, but for me it worked.
Java programmer here.
I'm trying to make a "plugin system" in java, and I would like ot make it so that the user can import their own java libraries if they needed to so they are not limited to only have my plugin loading application in their build path.
I was planning on allowing the user to make a folder called "lib" in their project, which is where they would put all the other libraries they needed, so they can then add those to the build path with the application erroring when loading all the necessary plugins. But, I am having trouble to do so.
Here is an example plugin jar file I have, that is structured the way I want it to be:
Plugin.jar
|---org
|---pluginpackage
|---PluginMainClass.class
|---lib
|---user-lib.jar
|---libpackage
|---InterfaceA.class
|---ClassB.class
|---...
|---plugin-description.xml
What I was wondering is this: What would be the most efficient way to load all the libraries the user has loaded inside the "lib" folder?
This is the current code I have, but it takes longer than desired to load the libraries:
private void readLibraryInJar(JarInputStream jarLibraryInputStream, File dirOut) throws IOException {
if (jarLibraryInputStream == null)
return;
JarEntry entry = null;
while ((entry = jarLibraryInputStream.getNextJarEntry()) != null) {
final String jarPath = entry.getName().trim();
if (jarPath.endsWith(".class")) {
File f = new File(dirOut, jarPath);
if (!f.exists()) {
if (!f.getParentFile().exists()) {
f.getParentFile().mkdirs();
}
f.createNewFile();
}
byte[] buffer = new byte[1024 * 100];
FileOutputStream out = new FileOutputStream(f);
int len;
while ((len = jarLibraryInputStream.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
out.close();
}
}
}
The above code reads each class file inside the desired library and copy's its content's into a new file. I know that a more efficient way is out there somewhere (e.g. Apache Tomcat project can have a "lib" folder), so I was wondering if I could load the library jar file more effeciently than I currently do (planning on using URLClassLoader to load it, so if you could transform it into a URL that would be awesome, but if that is impossible, I am still okay with any way more efficient than my current one.)
Thanks in advance!
I have developed an ExcelReader/Writer program that is intended to be ran on other computers. In this program, it takes in an excel.xls of hard data, reads it and writes it in a formatted way to an excel.xlsx file, and then saves it in a directory "CoC-Forms".
To reduce the steps to run my program, I have included the empty .xlsx file that it writes to in the project. However, when exporting it to an executable jar (to run on other computers), I seem to be having trouble accessing this empty form. I know this is probably a very simple answer, but I have been stuck for over a full work day and it has completely halted my progress.
Here is a snippet of my environment. On the left is my Project directory in Intellij (CoC.xlsx is the empty form) and the highlights on the right are where I am attempting to access the file and where the error is happening respectively.
JOptionPane.showMessageDialog(null,"About to look for CoC");
//fileFrom = new File(s + "/out/production/XML Reader/CoC.xlsx");
//fileFrom = new File("/XML Reader/out/production/XML Reader/CoC.xlsx");
//fileFrom = new File("CoC.xlsx");
//fileFrom = new File(ExcelWriter.class.getResource("CoC.xlsx").getPath());
CodeSource src = ExcelWriter.class.getProtectionDomain().getCodeSource();
/*if (src != null) {
URL url = new URL(src.getLocation(), "CoC.xlsx");
fileFrom = new File()
System.out.println(url);
} else {
JOptionPane.showMessageDialog(null,"Failed");
} */
fileFrom = new File(new File("."), "CoC.xlsx");
I solved my problem by having people download the whole project folder, file referencing with a ../../ from point of execution, and then going deeper into the file path to find the location at which I placed the file. Choppy, but it works and solved the problem.
I want to say I search a lot even google and stackoverflow. There are many topics about this but I dont find exactly what I need.
My problem is :
I want to define file which is in my own package folder.File's format is .txt.
And file is in xxx\src\xxxx\myTXTFile.txt
I write this code to reach my txt:
File f = new File(xxx.class.getResource("pr.txt").getFile());
When I run this code on netbeans yes it works.But when I compile and click .jar file it reports:
File not found
What can I do?
In the IDE the file still resides also outside the zip-format jar. Hence was found. For files inside the jar use:
OutputStream f = xxx.class.getResourceAsStream("pr.txt");
File does not work.
You can reach your txt-File with this code:
File f = new File("xxxx/myTXTFile.txt");
or you must save your txtfile in a Tempfolder:
InputStream is = getClass().getClassLoader().getResourceAsStream("xxxx/myTXTFile.txt");
OutputStream os = new FileOutputStream(new File("/tmp/tempTXTFile.txt"));
while ((i = is.read(buffer)) != -1)
{
output.write(buffer, 0, i);
}
output.close();
is.close();
File f = new File("/tmp/tempTXTFile.txt");
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.