JGit Removing a git repository - java

I am using JGit to clone a remote git repo using the below code.
localRepo = new FileRepository(path+"/.git");
git = new Git(localRepo);
clone = Git.cloneRepository().setURI(url).setBranch(branch)
.setDirectory(new File(path)).call();
clone.getRepository().close();
clone.close();
git.getRepository().close();
After cloning for the next repo, since I need to delete the directory, I use the below code.
File tempGitDirectory;
try {
tempGitDirectory = new File(dirPath);
if(tempGitDirectory.exists()){
FileUtils.deleteDirectory(tempGitDirectory);
}
} catch (IOException e) {
}
On my mac, everything works fine. But while trying on the redhat linux box, I am not able to delete the repo completely. Failing with the below error.
rm: cannot remove `git//TestGit/.nfs000000000011f6d40000032a': Device or resource busy
Any clue?

Make sure your pwd is not in the path you are trying to remove.
From this thread:
This occurs when a deleted file is still open by some process. It's an artifact of how NFS works behind the scenes.
An NFS server cannot actually remove a file if something still has it open.
The Linux kernel can easily do it with local disk files -- the inode still remains even after its unlinked from all directories, and the inode gets freed when the last process that has the file open terminates.
However this does not work with NFS, so the NFS server keeps this fake directory entry that represents an open file, and it will be automatically removed when whatever process has this file open terminates.
Check lsof in order to see what process is using the folder.
The OP Upen confirms in the comments:
I had opened a pom.xml reader for the cloned repo.
The FileReader was not closed. Works fine now.

Related

Open external .jar with Runtime.getRuntime().exec with java

So I have this code that works fine, it launch the .jar file from another machine that I have configure in my pc as a red ubication
Runtime.getRuntime().exec("java -jar Z:\\AAA\\BBB\\CCC\\ZZZ.jar");
But now I want to launch the .jar from that external path without using the shortcut before (so I can launch it with this code in a machine that dont have that red ubication configured)
Runtime.getRuntime().exec("java -jar MMM\\NNN LLL\\OOO\\AAA\\BBB\\CCC\\ZZZ.jar");
But doent work (I can access and open the file manually without a problem).
When I enter the java -jar MMM\\NNN LLL\\OOO\\AAA\\BBB\\CCC\\ZZZ.jar in the Command prompt it return me Error: Unable to access jarfile MMM\NNN, so perhaps one problem is that the path have a space in the folder name, but I think that may be something else too.
The question is, if the problem is the space, how I can solve it? I cant find a way. And in the other hand, how I can run it in another machine? I have to use that red ubication IP in some way instead?
PD: Using this code, it return me true
File f = new File("\\\\MMM\\NNN LLL\\OOO\\ZZZ.jar");
System.out.println(f.exists()); //--> true
So looks like the spaces dont interfere in the path (the four "\" doesnt seem to do anything in the tests when launching)
I have heard other people having such problems. The main reason for that is that probably Java exec method is not network (SMB) aware. So it doesn't even try to open from the network.
Anyway running the code like that from the network might not be the best solution. First of all the network might be unavailable, or the java file coming might be corrupted. If you want to do it properly you have several options:
Simple option that can work:
Create a bat file that works and exec that one - you can even copy the file locally first to make sure it is available first (if it is big and the network fails)
A better solution :
Use java to copy the file to the working directory and execute it from there.
A plus to do it like that by downloading is that you can maintain a version of the file (hash?) so you don't download it if it is the same. Or you can have fallback - execute the last downloaded version if the network drive is unavailable.
Use a local maven repository and dependency for that jar :)
This way it will keep the version of the jar locally and won't have to download it every time. It will also download a new version if available and the code will be more mainstream (for example not platform / pc dependent)
The answer give by #MadProgrammer works fine!
ProcessBuilder builder = new ProcessBuilder("java", "-jar", "MMM\\NNN LLL\\OOO\\AAA\\BBB\\CCC\\ZZZ.jar");
try {
builder.start();
} catch (IOException e) {
e.printStackTrace();
}
Lot of thanks! In any case going to check the ideas posted by Veselin Davidov

How to delete a file locked by the Java Platform?

I am currently developing an app which clones Git repositories thanks to JGit (http://wiki.eclipse.org/JGit/User_Guide) every time a user logs on. When the user wants to quit the app, I want to delete the clone.
Here's the problem : when cloning a repository, a folder .git is created, in which can be found a file .pack (.git/objects/pack/sutpideFile.pack) and which cannot be deleted, because the Java Platform is locking it (when trying to delete it by hand, get the error 'The action can't be completed because file is open in Java(TM) Platform SE binary').
THIS IS A KNOWN PROBLEM with Jgit : .pack file from git repo can't be deleted using File delete() method.
Thus I have used the solution proposed here : https://github.com/ajoberstar/grgit/issues/33 which is to add those three lines before my deleting method :
WindowCacheConfig config = new WindowCacheConfig();
config.setPackedGitMMAP(true);
WindowCache.install(config);
BUT what really bothers me because I do not understand is that this solution works only once: I launch the server (TomCat), connect, and then disconnect. Here, the whole folder is deleted. However, when I re-connect and disconnect (without re-launching the sever), there rebels the files and am I not able anymore to delete it until I shut down the server.
Has anybody the slighest idea why it works, but only once ?
Thanks for your help,
EDIT :
Well, so I just needed to add git.getRepository().close(); when I finish to use the Git object. Then the deletion is possible !
This is a know bug in JGit, see the discussion at How do I release file system locks after cloning repo via JGit
Basically you currently need to add the call to "Git.getRepository().close()" in order to free all file system locks until a new version of JGit is released.
result = Git.cloneRepository()
.setURI( 'https://github.com/github/testrepo.git' )
.setDirectory( localPath )
.call();
// this is currently necessary to free all file locks
result.getRepository().close();
result.close();
JGit 4.1 is scheduled to have a fix for this included.

jgit - Delete .git directory (or get files without it)

I need to clone a git repo in java. I am using jGit.
The line of code I am using is :
Git clone = Git.cloneRepository().setURI(URIofRepo).setDirectory(localPath).call();
Where URIofRepo is : the github link to my repo
and
Where localPath is : the directory I want the clone to happen.
This works perfectly. However, since the use of the project I am doing doesn't require a clone for continued work, I simply want the clone to have the contents of the github repo WITHOUT the .git directory.
I tried also using the following :
File dirToDelete = new File (path + "/.git");
FileUtils.deleteDirectory(dirToDelete);
However I got an IO exception saying I am unable to delete the file as follows :
Exception in thread "main" java.io.IOException: Unable to delete file:
C:\testing\testRepo1.git\objects\pack\pack-7ca7f11688adda065d62f3394d0e055346beff22.pack
It is possible that the current eclipse process keep an handle on the pack file, preventing its deletion.
As RĂ¼diger Herrmann suggests in the comments:
If the open file handle is what prevents the file from being deleted, make sure to close the repository that is returned by init:
clone.getRepository().close()
Another approach would be to download an archive of the GitHub repo through its archive link.
Or using JGit to create an archive from your current local repo (see ArchiveTest.java), and unzip that archive for you to use.
This issue of unable to delete local repository still persisted even after trying following:
clone.getRepository().close()
I could fix the issue and successfully delete local repository after setting "options" value to RECURSIVE delete while calling delete() as follows:
FileUtils.deleteDirectory(dirToDelete, 1);
This is what delete() document says:
public static void delete(File f, int options) throws IOException
Delete file or folder
Parameters: f - File to be deleted
options - deletion options, RECURSIVE for recursive deletion of a subtree, RETRY to retry when deletion failed. Retrying may help if the underlying file system doesn't allow deletion of files being read by another thread.
Whether or not your .close() will have an effect depends on how the repository was created. So even though you are calling close on a Git instance, it may or may not release the resources. I wasted so much of my time before I realized this.
From Jgit documentation :
If the repository was opened by a static factory method in this class, then this method calls Repository.close() on the underlying repository instance. (Whether this actually releases underlying resources, such as file handles, may vary; see Repository for more details.)
If the repository was created by a caller and passed into Git(Repository) or a static factory method in this class, then this method does not call close on the underlying repository.

Ending the process which is using the file on Mac OS X

For my application to work, I need to delete a file which is a Calendar Cache file on Mac. If I do it manually it goes to trash with no problems, it is just not emptying the trash afterwards, but it is fine for me. I tried to run my Java application with a method to delete that same file but the method failed. I used file.delete() method. Are there any ways of deleting that file? Is there a way to stop the process that is using that file? Thank you for your help.
Try something like this:
File fin = new File("yourfile.txt");
for (File file : fin.listFiles()) {
FileDeleteStrategy.FORCE.delete(file);
}

File gets deleted on Linux but not on Windows

So I have this program in Java, where I make a file, write to it and save it.
But after the program finishes it's job, I want it to delete the file it created.
Here is the code with which I make the file and delete it:
RandomAccessFile file = null;
file = new RandomAccessFile("myFile.zip", "rw");
file.write(buffer,0,read);
file.close();
File file = new File("myFile.zip");
file.delete();
It cannot be related to how Windows and Linux use their file paths ( \ or /) as I don't really specify it other than showing it to be at the root of my project.
So what might be the case in this situation?
Windows notices the open file handle and refuses to delete the open file. That's a policy in Windows. Files which are open do not disappear. The process holding the open file handle can rely on that the file will stay.
Linux has a different policy. There a file can be deleted from all directories (yes, it can be in more than one when it is hard linked), even if a process still has an open handle on it. The file itself will then not be removed from the disk. The process using the open handle can still process the file, make it grow, shrink it, write to it, read from it. But after the handle gets closed, the file gets removed automatically by the file system.
These different policies of the to OSes you are using are the reason for your observation.

Categories

Resources