0

I am facing a strand kind of issue in multi threaded environment. Though this code was pretty old and was working since long time.

One of the person complained that they are facing issue like. Even though the file created by one thread exist , another thread saying no file exist.

I providing a sample method where the problem is coming..

/**
  * Creates a temporary directory. Will be deleted when the program closed if it
  * is empty!
  *
  * @return the temporary directory
  * @throws com.osm.exception.WMException if there is a problem
  */
public static File createTempDir() throws WMException {
    synchronized (pdm.semaphore) {
        try {
            final File parent = WMSession.getWMSession().getRootTempDir();
            if (!parent.exists()) {
                throw new IllegalStateException(parent + " does not exist"); //frozen
            }

            final File tmpDirectory = File.createTempFile("WMTempDir", "", parent); //frozen
            tmpDirectory.delete();
            tmpDirectory.mkdirs();
            logFileCreated(tmpDirectory);
            return tmpDirectory;
        } catch (final IOException ioe) {
            throw new WMException(ioe);
        }
    }
}

This code is being called from another method code as below.

void copy_from_db2_using_temp_dir(String phys_name, int storage_type, int store_date, int file_flag,
        String directory, String file_name) throws WMException {
        final File destDir = new File(directory);

        if (!destDir.exists()) {
            // no conflict possible since destination directory does not yet exist.
            pdm.copy_from_db2(phys_name, storage_type, store_date, file_flag, directory, file_name);

            return;
        }

        final File tmpDir = WMFile.createTempDir();
        final File tmpDestFile = new File(tmpDir, file_name);
        final File destFile = new File(directory, file_name);

        try {
            final boolean destFileExistsFlag = destFile.exists();

            if (destFileExistsFlag && (file_flag != DEL_OLD)) {
                final String msg = pdm.fix_mesg(pdm.catgets("data_mgr", 266, "*** ERROR: Cannot overwrite file '{1}'"),
                        destFile.getAbsolutePath());
                throw new WMException(msg);
            }

            pdm.copy_from_db2(phys_name, storage_type, store_date, file_flag, tmpDir.getAbsolutePath(), file_name);

            if (tmpDestFile.isFile() && destFile.isDirectory()) {
                final String msg = pdm.fix_mesg(pdm.catgets("data_mgr", 269, "*** ERROR: Could not remove file '{1}'"),
                        destFile.getAbsolutePath());
                throw new WMException(msg);
            }

            moveFiles(tmpDestFile, destFile, (file_flag == DEL_OLD));
        } finally {
            deleteTempDir(tmpDir);
        }
    }

The another thread/process always getting the condition !parent.exists() true. Which is incorrect as it must get the parent file.

Need suggestion input or any logging that will helpful to know if the invocation has some issue or some issue in the code.

I got something on StackOverflow but not sure if that is relevant here. File.exists() issue in multi threaded env

CodeMatrix
  • 2,124
  • 1
  • 18
  • 30
vibhas
  • 1,449
  • 4
  • 18
  • 32

1 Answers1

0

if (!parent.exists()) { in your createTempDir function is triggered, because the parentFolder of the file that you are trying to create does not exist. This has nothing to do with multithreading.

Example:

Lets say we are trying to create the folder C:\myGame\logs in the createTempDir method. Your code will first test to see if C:\myGame exists. If it does not exist, then your code will throw an illegal state exception and not continue execution.

In other words: the parent directory in which you want to create your logs directory does not exist. This could be due to a number of reasons:

  • WMSession.getWMSession().getRootTempDir() is not properly configured: it points to a wrong filepath.

  • Perhaps you don't even need to assert that the parent directory exists. Because you call mkdirs() in your code, all required ancestor-directories for your logs directory will be automatically created.

You can consider the following solutions:

  • Properly configure WMSession so that it points to the correct folder, assuming that you want the parent directory to exist in advance of your code execution.

  • Simply don't care about if the parent directory exists, as mkdirs handles this for you.

ImJustACowLol
  • 826
  • 2
  • 9
  • 27
  • WMSession.getWMSession().getRootTempDir() gives the fileName when it is executed for 1st thread let say. But even though its there the 2nd thread returns a false value. Not sure what do you mean by not properly configured. – vibhas Jan 23 '19 at 14:48
  • @vibhas I'm saying that `WMSession.getWMSession().getRootTempDir();` does not exist. The directory that that function returns, is not available on the machine. Therefore, the function is either returning a wrong filepath OR you are checking if the folder exists, while you don't have to. – ImJustACowLol Jan 23 '19 at 15:07