Quantcast
Channel: Resources not being released - Stack Overflow
Viewing all articles
Browse latest Browse all 4

Resources not being released

$
0
0

We have a legacy system that has a admim module that allows users to upload jar files. After the upload, the jar file is validated and if not compliant to internal rules, it is deleted.

The problem is that windows is throwing an exception telling that the file "is already being used by another process." (when I call Files.delete(tmpJar);). I'm not able to identify why the file is open. Seems to me that I have closed everything.

First, we are using primefaces (4.0) to upload the file. Primefaces relies on commons-fileupload (1.3.1). It call the following method:

public void handleFileUpload(FileUploadEvent event) {   Path tmpJar = null;   try {      tmpJar = Files.createFile(Paths.get(event.getFile().getFileName()));      Files.write(tmpJar, event.getFile().getContents());   } catch (IOException e) {      LOGGER.error(e.getMessage(), e);   }   if (tmpJar != null) {      try {         this.validateJar(tmpJar.toString());         Files.delete(tmpJar);      } catch (IOException e) {         LOGGER.error(e.getMessage(), e);      }   }}

Before NIO Files.write, I was using "standard" java IO classes. The problem isn't related to the above code, because if I comment the call to validateJar, Files.delete(tmpJar) is executed without problems and the file is removed. So, the problem is related with the code below, but I can't find where...

Job is an internal class, basically a simple POJO. "jobAnnotation" is a custom annotation to identify Jobs. I have shortened the code, but the essencial parts are preserved.

private List<Job> validateJar(final String jarPath) throws IOException {   List<Job> jobs = new ArrayList<Job>();   try (JarFile jarFile = new JarFile(jarPath)) {      URL[] jars = { new URL("file:"+ jarPath) };      ClassLoader jobClassLoader = URLClassLoader.newInstance(jars, this.getClass().getClassLoader());      Enumeration<JarEntry> jarEntries = jarFile.entries();      while (jarEntries.hasMoreElements()) {         JarEntry jarEntry = jarEntries.nextElement();         String className = jarEntry.getName();         Class<?> classToLoad;         try {            classToLoad = Class.forName(className, true, jobClassLoader);         } catch (Exception e1) {            LOGGER.error(e1.getMessage(), e1);            continue;         }         if (classToLoad.isAnnotationPresent(jobAnnotation)) {            String vlr = null;            try {               Class<?> jobClass = (Class<?>) Class.forName(classToLoad.getCanonicalName(), true, jobClassLoader);                Annotation annotation = jobClass.getAnnotation(jobAnnotation);                Method method = annotation.getClass().getMethod("getValue");                vlr = ((String) method.invoke(annotation, new Object[0]));            } catch (Exception e1) {               LOGGER.error(e1.getMessage(), e1);            }            Job job = new Job();            job.setEnabled(true);            job.setJarfile(jarPath);            job.setClassName(classToLoad.getName());            Parameter parameter = new Parameter();            parameter.setRequired(true);            parameter.setName("name");            parameter.setValue(vlr);            job.addParameter(parameter);            jobs.add(job);         }      }   } catch (IOException e) {      throw e;   }   return jobs;}

Before using try-with-resources, I was using regular try-catch-finally to close the JarFile, thats the only thing that has a explicit close method. Probably is the classloading that is holding the file open, but I don't know how to close it.

I did some searches, and I found that I can't unload classes (Unloading classes in java?).

So, the problem is, how do I release it? Or how can I remove the file?

BTW, I'm using java 1.7.0_71, jboss 7.1.1, windows 7 (64).


Viewing all articles
Browse latest Browse all 4

Latest Images

Trending Articles





Latest Images