views:

224

answers:

2

Say you have a large legacy ColdFusion on top of Java on top of Windows application. File access is done both via java.io.File and by CFFILE (which in turn also uses java.io.File), but not centralised in any way into a single file access library. Further, say you have file paths both hard-coded in the code, and also in a database.

In other words, assume the file paths themselves cannot change. They could be either local or remote Windows file paths:

  • c:\temp\file.txt
  • \\server\share\file.txt

Is there a way to run this application on Linux with minimal code changes? I'm looking for creative solutions that do not involve touching the legacy code.

Some ideas:

  • Run it on WINE. This actually works, because WINE will translate the local paths, and has a samba client for the remote paths.
  • Is there a way to override java.io.File to perform the file path translation with custom code? In this case, I would translate the remote paths to a mount point.
+2  A: 

The java.io.File is not a final class, and can be extended. In your extension you could have one (or more) constructors that will translate the file paths. This would only require you to write the translator, and change every initialisation of File to you extended class.

Since your class would extend java.io.File there is no other code change required other then changing the initialisation.

java.io.File file1 = new ClassThatExtendsFile("C:\temp\file.txt");

[edit]: or you could extend the CFFILE, and override it's constructors.

jex
What I want to avoid is touching the legacy code everywhere a CFFILE or java.io.File is used. Now, if I could replace java.io.File with my own implementation, that would do it.
Chase Seibert
To do that, he would have to modify the source code and in that case it would be better if he changes the paths in the process.
OscarRyz
+5  A: 

Is there a way to override java.io.File to perform the file path translation with custom code? In this case, I would translate the remote paths to a mount point

Yes, you can perform your own implementation of java.io.File and place it in a separate jar and then load it instead of the real java.io.File.

To have the JVM load it you can either use the java.endorsed.dirs property or java -Xbootclasspath/p:path option in the java launcher ( java )

BUT!!!

Creating your own version of the java.io.File class won't be as easy as modifying the legacy source code.

If you're afraid of breaking something you could first extract all your hardcoded paths to use a resource bundle:

So:

 File file = new File("C:\\Users\\oreyes\\etc.txt");

Would be:

File file = new File( Paths.get( "user.dir.etc" ));

And Paths would have a resource bundle internally

class Paths {
    private static ResourceBundle rs = ResourceBundle.getBundle("file.paths");
    public static String get( String key ) {
        rs.getString( key );
    }
}

You can have all this hardcoded paths extraction with an IDE ( usually an internationalization plugin )

Provide a different resource bundle for Linux and your done. Test and re-test and re-test

So, use provide your own java.io.File only as a last resource.

OscarRyz
I ended up prototyping my own java.io.File by downloading the latest version from the JDK and branching it. I'm working on an AoP solution that would be more maintainable.
Chase Seibert
That's sound like hours or fun!! :)
OscarRyz