Search code examples
javacoldfusionpdfboxcoldfusion-2016

ColdFusion 2016 Java ClassNotFoundException


I have downloaded the PDFBox jar file and have placed it under the {application.home}\lib folder. PDFBox has a few other assistant jar files. I have placed all of them in {application.home}\lib folder, too. I restarted the ColdFusion 2016 service.
In my code file, I have some very simple test lines.

  <cftry>

    <cfset local.pdfUnitObj = CreateObject("java", "org.apache.pdfbox.pdmodel")>
    <cfcatch type="any">
      <cfdump var="#cfcatch#" output="C:\inetpub\wwwroot\cfcatcherr.txt">       
    </cfcatch>
  </cftry>

In the cfcatcherr.txt, I keep on getting an error saying, java.lang.ClassNotFoundException: org.apache.pdfbox.pdmodel

In org.apache.pdfbox.pdmodel, there is a PDDocument class. I have tried referencing org.apache.pdfbox.pdmodel.PDDocuemtn but it is still giving me the error. I have placed all those files under {application.home}\jre\lib and {application.home}\wwwroot\WEB-INF\lib. The error is still the same thing. Is it because I didn't place the jar file in the correct location? Anybody knows how I can get this problem resolved please?


Solution

  • Preferred method for CF2016+

    Instead of mucking about with the class path and having to restart the server each time, there's a simpler option for CF2016+. Load the jars dynamically in your Application.cfc using this.javaSettings. The LoadPaths parameter accepts an array of one or more directories (containing jar files to be loaded):

    component {
        this.name = "YourAppName";
        // loads all jars in the subdirectories named "lib" and "ext"
        this.javaSettings = { LoadPaths = [ ".\lib\", ".\ext\" ] };
    }
    

    .. or supply an array of individual jar file paths:

    component {
        this.name = "YourAppName";
        // loads individual jars 
        this.javaSettings = { LoadPaths = [ "C:\path\to\pdfbox-2.0.16.jar"
                                            , "C:\path\to\xmpbox-2.0.16.jar"
                                            , .. more paths
                                          ]
                            };
    }
    

    Adrian J. Moreno also pointed out another advantage of this approach:

    Much easier to check the JARs in with your code base and deploy to servers instead of having to document for DevOps to remember to put JAR X in location Y should you need to upgrade or build a new server.


    Old method

    However, to answer your earlier questions, the most common causes of ClassNotFoundException are:

    1. Wrong class name

      CreateObject expects a class name (cAsE sEnSiTiVe).

    2. Jar files aren't in the CF class path

      Aside from the core JVM paths, CF only scans locations listed in Server Settings > ColdFusion Class Path. Jar files placed elsewhere won't be detected. (The default CF class path includes the WEB-INF\lib directory)

      Placing multiple copies of a library in the class path can sometimes cause errors. Though in my experience, that issue usually causes a different error.

    3. Forgetting to restart the CF server

      Aside from the core JVM paths, the CF server only scans the class path locations on start up. So the CF server must be restarted in order to detect any new jars.

    Your error is caused by #1 - Wrong class name. org.apache.pdfbox.pdmodel is the name of a package - not a class. The class name should be org.apache.pdfbox.pdmodel.PDDocument (note the spelling of PDDocument).