Reading file creation time in CFML using the java.nio.file package

UPDATE

The issue with the getClass() method not working on Java Interfaces is limited to the Lucee engine, and a patch has been created to address it.

--

CFML is a language that provides lots and lots of shortcuts for doing things in Java, which make ColdFusion, Railo, and Lucee good languages for rapid application development. However, there are things that you can't do in CFML directly, and in most cases the solution is to drop down to Java, either implementing an existing Java library, or writing something in Java as your solution.

Writing entire Java classes for smallish operations is somewhat against the spirit of CFML, which gives you some ability to use Java classes directly rather than writing a wrapper in Java for the functionality you need.

It isn't always easy, though, because the pecularities of CFML limit how much you can do with Java from within the CFML environment.

A user on the Lucee mailing list recently asked a question related to how to get the creation time of a file using Java. His question specifically was about how to get the .class name of the java.nio.file.attribute.BasicFileAttributes Java interface. It seems like you can't get that value in CFML, at least from the user's tests, which I confirmed. (See update above).

As with most things in Java, though, there is more than one way to accomplish a given task. In this case, you can use the java.nio.file.Files class to read the file attributes.

<cfscript>
    paths = createObject("java", "java.nio.file.Paths" );
    path = paths.get( "/Users/rmunn/lucee", [] );
    //options = createObject("java", "java.nio.file.LinkOption" );
    attrs = createObject("java", "java.nio.file.Files" ).readAttributes( path, "*", [] );
</cfscript>

<cfdump var='#attrs.creationTime.toString()#'>

 

Using this technique, you can get any file attributes available to Java from within CFML, without having to write a wrapper class in Java to solve the problem.

The larger questions of why there are such limits on what you can do with Java from within the CFML environment has to do with the nature of typing in CFML v. Java. CFML is dynamically typed, and its object-oriented features are entirely optional, as you can write even very large programs in CFML without any OO features whatsoever. Because of these and other reasons, you can't just write a bunch of Java code inside a CFML page and expect the CFML engine to know what to do with it.

CFML has a very specific interface for interacting with Java, using the built-in createObject() method. It also includes a javacast() method that has some ability to cast data types specifically to types that Java understands, but that's about it as far as working directly with Java classes. You can still solve a lot of problems using these methods, you just might need to do some experimenting beyond copying the first Java tutorial you find that describes a way to solve the problem.

If you find yourself in a position of needing to write a Java wrapper for your solution, make sure to use Mark Mandel's excellent JavaLoader, which provides an easy way to load custom Java classes inside CFML.