jar compile Runtime.getRuntime.exec() full directory in jar - java

Just for fun I'm making a little Java project file to keep on my dropbox to compile java for me without an ide easier than typing all those pesky command line arguments myself.
Right now I am just having one small problem...
First here's my code which does manage to compile class files into a jar with a manifest.
public static String listFilesString(String dirLocation){
String allPaths = ""; //pretty self explanatory returns full list of files in directory with spaces
File f = new File(dirLocation);
if(f.isDirectory()&&f.list().length>0){
for(File f2 : f.listFiles()){
if(f2.isDirectory()){
allPaths = allPaths + listFilesString(f2.toString());
} else {
allPaths = allPaths + f2.toString() + " ";
}
}
}
return allPaths;
}
public static boolean compileOutputToJar(String output, String jarLocation){
output = output.replace('\\', '/'); //replacements just for uniformity
String binF = WorkspaceVariables.workspaceDir+output;
String toCompile = listFilesString(binF).replace('\\', '/');
try {
Runtime.getRuntime().exec("jar cvfm " + jarLocation + " " + binF + "manifest.txt " + toCompile); // this line represents the problem
System.out.println("Compiled Workspace to Jar!");
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
As is commented on the line containing Runtime.getRuntime().exec("jar cvfm " + jarLocation + " " + binF + "manifest.txt " + toCompile); this is where the problem occurs. Indeed the command properly executes but I do provide the full path to the class files to be compiled into the jar.
As an example I'll use the sample project this compiles. with a directory structure of:
/bin/manifest.txt < The manifest is compiled properly
/bin/Main.class < Calls k.Me to get the n variable which is printed
/bin/k/Me.class < Defines a string 'n' equal to "hi"
this however is compiled into the jar as:
META_INF/MANIFEST.MF
Users/MYUSERNAME/Desktop/Other/ide/javas/bin/Main.class
Users/MYUSERNAME/Desktop/Other/ide/javas/bin/manifest.txt < Nevermind this inclusion, just a problem I've not fixed.
Users/MYUSERNAME/Desktop/Other/ide/javas/bin/k/Me.class
The problem is clear, the file cannot run while it's like this and it is plainly compiled incorrectly. I could compile it correctly by changing to the directory they're found in before execution (not found a way to do this). Or possibly changing the location during command execution (I've tried using -cp, but to no avail).
The best option seems to be the use of -C as it can move the Main.class and manifest.txt to the proper place, however it doesn't include sub-directories to Me.class and the k folder no longer exist. and adding this to the beginning of each files name by adding "-C " + f2.getParent() + " ". in the listFilesString method prevents any of the class files from compiling into the jar at all.
Thanks for any help/ contributions!

One line was missing, a slight adjustment I've made corrected the error.
public static String listFilesString(String dirLocation){
String allPaths = ""; //pretty self explanatory returns full list of files in directory with spaces
File f = new File(dirLocation);
if(f.isDirectory()&&f.list().length>0){
for(File f2 : f.listFiles()){
if(f2.isDirectory()){
allPaths = allPaths + f2.toString() + " "; //THIS LINE WAS ADDED
allPaths = allPaths + listFilesString(f2.toString());
} else {
allPaths = allPaths + f2.toString() + " ";
}
}
}
return allPaths;
}
public static boolean compileOutputToJar(String output, String jarLocation){
output = output.replace('\\', '/'); //replacements just for uniformity
String binF = WorkspaceVariables.workspaceDir+output;
String toCompile = listFilesString(binF).replace('\\', '/');
try {
Runtime.getRuntime().exec("jar cvfm " + jarLocation + " " + binF + "manifest.txt " + toCompile); // this line represents the problem
System.out.println("Compiled Workspace to Jar!");
return true;
} catch (IOException e) {
e.printStackTrace();
return false;
}
}

Related

java.io.File.isFile() returning false on a mapped drive file, however cmd is able to list the contents

Created a Mapped Drive [Z:], which is created against a IBMi share by the command
NET USE Z: \IBMiMachine\PROD /USER:USER1 *******
The drive is created successfully.
Then tried to list all files (e.g. .php/.txt/.html etc) present under the mapped drive, by a simple Java program (using Java 7 IO APIs, and the Java class resides in a runnable jar myjar.jar) by running the command
java -jar myjar.jar Z:
So noticed that java.io.File.isFile() returning the false against the various file:
File: 'Z:\ABC\20100709\Info.php'
isSymbolicLink -- false
isDirectory -- true
exists: true
is file: false
can read: true
can write: true
is hidden: false
File: 'Z:\ZYZ\20100607\intranet\Int.php'
isSymbolicLink -- false
isDirectory -- true
exists: true
is file: false
can read: true
can write: true
is hidden: false
also the java.io.File.isDirectory() also saying those are directories; But those files contents can be seen on command prompt by the command "CAT <file_name>".
My Java Program code like this:
private static int counter = 1;
public static void main(String[] args)
{
if (Utils.length(args) == 0)
{
print("Either passed argument was empty or null: " + Arrays.toString(args));
return;
}
print("Passed argument was: " + Arrays.toString(args));
doFile(new File(args[0]));
}
private static void doFile(File folder)
{
if (folder.isDirectory())
{
showFileAttributes1(folder);
showFileAttributes2(folder);
String files[] = folder.list();
int length = (files == null) ? 0 : files.length;
for (int i = 0; i < length; i++)
{
doFile(new File(folder, files[i]));
}
}
else if (folder.isFile())
{
showFileAttributes1(folder);
showFileAttributes2(folder);
}
}
private static void showFileAttributes1(File folder) throws IOException
{
print("");
print(" " + counter++ + ". File: '" + folder.getPath() + "' ---------");
Map<String, Object> fileAttributes = Files.readAttributes(folder.toPath(), "*");
Iterator<String> iterator = fileAttributes.keySet().iterator();
while (iterator.hasNext())
{
String key = iterator.next();
print(key + " -- " + fileAttributes.get(key));
}
}
private static void showFileAttributes2(File file) throws IOException
{
print("exists: " + file.exists());
print("is file: " + file.isFile());
print("can read: " + file.canRead());
print("can execute: " + file.canExecute());
print("can write: " + file.canWrite());
print("is hidden: " + file.isHidden());
Path filePath = Paths.get(file.getAbsolutePath());
//Is file readable
boolean isReadable = Files.isReadable(filePath);
print("Is file readable: " + isReadable);
//Is file writable
boolean isWritable = Files.isWritable(filePath);
print("Is file writable: " + isWritable);
//Is file executable
boolean isExecutable = Files.isExecutable(filePath);
print("Is file executable: " + isExecutable);
}
private static void print(String message)
{
System.out.println(message);
}
What approach can be taken to overcome of Java problem??
Note: I have the same full access rights on that machine/folder, since by the ROBOCOPY command I am able to copy complete folder structure of mapped drive into my local drive, and then no issue of Java API on that folder then
ROBOCOPY Z: C:\mysource *.php /E /log:log.txt

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 .

Recursion method continues after returning value?

I'm writing a quick Java recursion method that, given a root folder and filename, searches your files for said file name.
import Java.io.File;
public static String searchForFile(File currentFolder, String filename)
{
try
{
File[] path = currentFolder.listFiles();
for (int i = 0; i < path.length; i++)
{
if (path[i].isDirectory())
{
System.out.println("Directory: " + path[i].toString());
searchForFile(path[i], filename);
}
else
{
System.out.println("File: " + path[i].toString());
if(path[i].getName().equals(filename))
{
System.out.println("Your file has been found!";
return path[i].toString();
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
return null; // Omitting this line yields compiling errors, not sure why?
}
public static void main(String[] args)
{
System.out.println("Hello, enter the root folder and file name.");
String rootFolder = "Desktop";
String fileName = "Hello.txt";
File f = new File("C:\\Users\\Me\\" + rootFolder);
searchForFile(f, fileName);
}
The program itself technically works, however searchForFile() keeps iterating even after the requested file is found. For example, I'd get an output such as:
File: C:\Users\Me\Desktop\My Stuff\NotHello.txt
**File: C:\Users\Me\Desktop\My Stuff\Hello.txt**
Your file has been found!
File: C:\Users\Me\Desktop\My Stuff\AlsoNotHello.txt
File: C:\Users\Me\Desktop\My Stuff\StillNotHello.txt
File: C:\Users\Me\Desktop\My Stuff\WhyIsThisMethodStillRunning.txt
I've been scratching my head at this for awhile now. I thought return always exits the method, so why does the recursion continue even after it returns a value? I haven't found any similar questions asked, so any help would be much appreciated!
(Also, how could I edit the method so that it returns a blank "" string if the requested file is not found?)
You are returning from the innermost call, when you've found the file. But when you are scanning a directory, you are not using the return value.
Change this:
searchForFile(path[i], filename);
to:
String result = searchForFile(path[i], filename);
if (result != null) {
return result;
}
The return null; in the bottom of your method is there because all methods needs to return a value. No matter if the file is found or not. If the file is not found within the current directory (or one of its subdirectories), you can return null; to indicate that it wasn't found.
Side suggestion: Use Optional in Java 8 instead of null.

mysqldump creates a blank file using java

Goodmorning everyone.
I have a problem with my java program: i would like to create a directory to store a .sql file, which will be generated through mysqldump.exe. I've been trying to follow guides on Stack Overflow or others, but i still can't resolve my problem: directory and .sql file are generated, but the file is totally blank. The best part is that pasting the same command (ctrl+C, ctrl+V) on the command line, it works well and generates an ordinary .sql file for a dump operation.
Please help me. I'm using NetBeans 8.0.2 as IDE, there's my code (there are some variables, like SelectedTable, that allows me to get the current user, password etc. Don't care about them: those parts works and the command is correctly generated):
private void jMenuExternalBackupActionPerformed(java.awt.event.ActionEvent evt) {
LocalDate today = LocalDate.now();
GregorianCalendar now = new GregorianCalendar();
String BackupFolderName = SelectedTable.getMaster().getName()+" "+SelectedTable.getName()+" "+today.getYear()+"_"+today.getMonth().getValue()+"_"+today.getDayOfMonth()+" "+now.get(now.HOUR_OF_DAY)+"_"+now.get(now.MINUTE)+"_"+now.get(now.SECOND);
new File("/HyperSQL/Backups/").mkdirs();
new File("/HyperSQL/Backups/"+BackupFolderName+"/").mkdirs();
String command;
if (SelectedTable.getMasterApplication().getPassword().isEmpty())
command = "mysqldump -u" + SelectedTable.getMasterApplication().getUserLogged() + " " + SelectedTable.getMaster().getName() + ""
+ " > \"C:\\HyperSQL\\Backups\\"+BackupFolderName+"\\backup.sql\"";
else
command = "mysqldump -u" + SelectedTable.getMasterApplication().getUserLogged() + " -p" + SelectedTable.getMasterApplication().getPassword() + " " + SelectedTable.getMaster().getName() + ""
+ " > \"C:\\HyperSQL\\Backups\\"+BackupFolderName+"\\backup.sql\"";
try
{
Process exec = Runtime.getRuntime().exec(new String[]{"cmd.exe","/c", command});
}
catch (Exception e)
{
e.printStackTrace();
}
}

Open file to view its content [duplicate]

This question already has answers here:
How to open a file with the default associated program
(4 answers)
Closed 9 years ago.
I have a files list. Lets say it looks:
String[] lst = new String[] {
"C:\\Folder\\file.txt",
"C:\\Another folder\\another file.pdf"
};
I need some method to open these files with default program for them, lets say "file.txt" with Notepad, "another file.pdf" with AdobeReader and so on.
Does anyone knows how?
There is a method to do this:
java.awt.Desktop.getDesktop().open(file);
JavaDoc:
Launches the associated application to open the file.
If the specified file is a directory, the file manager of the current platform is launched to open it.
The Desktop class allows a Java application to launch associated applications registered on the native desktop to handle a URI or a file.
If you are using J2SE 1.4 o Java SE 5, the best option is:
for(int i = 0; i < lst.length; i++) {
String path = lst[i];
if (path.indexOf(' ') > 0) {
// Path with spaces
Runtime.getRuntime().exec("explorer \"" + lst[i] + "\"");
} else {
// Path without spaces
Runtime.getRuntime().exec("explorer " + lst[i]);
}
}
Just make sure the file is in the right location, and this should work fine.
try
{
File dir = new File(System.getenv("APPDATA"), "data");
if (!dir.exists()) dir.mkdirs();
File file = new File(dir"file.txt");
if (!file.exists()) System.out.println("File doesn't exist");
else Desktop.getDesktop().open(file);
} catch (Exception e)
{
e.printStackTrace();
}
I didn't know you have a String array now. So, this one uses regex to process the file list in the format you specified before. Ignore if not required.
If the file list is huge and you would prefer that the files open one by one cmd works great. If you want them to open all at once use explorer. Works only on Windows but then on almost all JVM versions. So, there's a trade-off to consider here.
public class FilesOpenWith {
static String listOfFiles = "{\"C:\\Setup.log\", \"C:\\Users\\XYZ\\Documents\\Downloads\\A B C.pdf\"}";
public static void main(String[] args) {
if (args != null && args.length == 1) {
if (args[0].matches("{\"[^\"]+\"(,\\s?\"[^\"]+\")*}")) {
listOfFiles = args[0];
} else {
usage();
return;
}
}
openFiles();
}
private static void openFiles() {
Matcher m = Pattern.compile("\"([^\"]+)\"").matcher(listOfFiles);
while (m.find()) {
try {
Runtime.getRuntime().exec("cmd /c \"" + m.group(1) + "\"");
// Runtime.getRuntime().exec("explorer \"" + m.group(1) + "\"");
} catch (IOException e) {
System.out.println("Bad Input: " + e.getMessage());
e.printStackTrace(System.err);
}
}
}
private static void usage() {
System.out.println("Input filelist format = {\"file1\", \"file2\", ...}");
}
}

Categories

Resources