I am supporting a ColdFusion 8 website running on Windows Server 2003 R2 (with all Windows Security Updates applied). The website functions smoothly 99.9% of the time. However, about 2 months ago, the ColdFusion 8 Application Server service started crashing and restarting itself every night at 10:30 PM. There is a ColdFusion Scheduled Task that runs at 10:30 PM every night, so I tried running it manually (direct URL in a browser), and sure enough the ColdFusion 8 Application Server service crashed and restarted. So, it's obviously this one template that is causing this to happen.
What this template does is read a directory full of PDF files, then loop through those files to create several thumbnail images for each using CFPDF. This Scheduled Task has been running for years without this issue. The CF service appears to be crashing/restarting almost immediately, before a single file is processed.
I tried running the same template in our Staging environment, and it ran fine - no CF restart. I'm very confused.
Searched through the ColdFusion logs and found nothing.
UPDATE:
Code sample:
<cffunction name="createThumbnails" returntype="Void" output="false">
<cfargument name="sourcePath" type="String" default="" />
<cfargument name="overwriteExisting" type="Boolean" default="true" />
<cfargument name="deleteSourceFile" type="Boolean" default="false" />
<cfset var _image = {} />
<cfif FileExists(ARGUMENTS.sourcePath)>
<cfif ARGUMENTS.overwriteExisting
OR NOT FileExists(getXLargeThumbnailPath())>
<!--- Large Image for MACXpress --->
<cfset _image =
REQUEST.UDFLib.Image.scale(
imagePath = ARGUMENTS.sourcePath,
maxHeight = 777,
maxWidth = 627
) />
<cfimage
action="write"
source="#_image#"
overwrite="true"
destination="#getXLargeThumbnailPath()#" />
</cfif>
<cfif ARGUMENTS.overwriteExisting
OR NOT FileExists(getXLargeThumbnailPath())>
<cfset _image =
REQUEST.UDFLib.Image.scale(
imagePath = ARGUMENTS.sourcePath,
maxHeight = 211,
maxWidth = 215
) />
<cfimage
action="write"
source="#_image#"
overwrite="true"
destination="#getXLargeThumbnailPath()#" />
</cfif>
<cfif ARGUMENTS.overwriteExisting
OR NOT FileExists(getLargeThumbnailPath())>
<cfset _image =
REQUEST.UDFLib.Image.scale(
imagePath = ARGUMENTS.sourcePath,
maxHeight = 265,
maxWidth = 215
) />
<cfimage
action="write"
source="#_image#"
overwrite="true"
destination="#getLargeThumbnailPath()#" />
</cfif>
<cfif ARGUMENTS.overwriteExisting
OR NOT FileExists(getMediumThumbnailPath())>
<cfset _image =
REQUEST.UDFLib.Image.scale(
imagePath = ARGUMENTS.sourcePath,
maxHeight = 100,
maxWidth = 100
) />
<cfimage
action="write"
source="#_image#"
overwrite="true"
destination="#getMediumThumbnailPath()#" />
</cfif>
<cfif ARGUMENTS.overwriteExisting
OR NOT FileExists(getSmallThumbnailPath())>
<cfset _image =
REQUEST.UDFLib.Image.scale(
imagePath = ARGUMENTS.sourcePath,
maxHeight = 50,
maxWidth = 50
) />
<cfimage
action="write"
source="#_image#"
overwrite="true"
destination="#getSmallThumbnailPath()#" />
</cfif>
<cfscript>
if (ARGUMENTS.deleteSourceFile) {
try {
FileDelete(ARGUMENTS.sourcePath);
}
catch (any e) {
}
}
</cfscript>
</cfif>
</cffunction>
REQUEST.UDFLib.PDF:
<cffunction
name="pdfToImageFile"
returntype="String"
output="false"
hint="Converts a phsyical PDF File to a physical Image file and returns the absolute path of the new Image file">
<cfargument name="sourcePath" type="String" default="" />
<cfargument name="destinationPath" type="String" default="" />
<cfargument name="format" type="String" default="png" />
<cfset var LOCAL = {} />
<cfif NOT isValidPDF(Trim(ARGUMENTS.sourcePath))>
<cfthrow
message="Source file not specified or not a valid PDF file." />
</cfif>
<cfif NOT DirectoryExists(Trim(ARGUMENTS.destinationPath))>
<cfthrow message="Inavlid Destination path." />
</cfif>
<cfif
NOT ListFindNoCase(
GetWriteableImageFormats(),
Trim(ARGUMENTS.format)
)>
<cfthrow message="Inavlid Image format specified." />
</cfif>
<cfscript>
LOCAL.DestinationFilePath =
Trim(ARGUMENTS.destinationPath)
& "\"
& VARIABLES.Library.File.getFileNameWithoutExtension(
GetFileFromPath(ARGUMENTS.sourcePath)
)
& "."
& LCase(Trim(ARGUMENTS.format));
LOCAL.RandomAccessFile =
CreateObject("java", "java.io.RandomAccessFile")
.init(
CreateObject("java","java.io.File")
.init(ARGUMENTS.sourcePath),
"r"
);
LOCAL.FileChannel = LOCAL.RandomAccessFile.getChannel();
</cfscript>
<cftry>
<cfset LOCAL.PDFFile =
CreateObject("java", "com.sun.pdfview.PDFFile")
.init(
LOCAL.FileChannel.map(
CreateObject("java", "java.nio.channels.FileChannel$MapMode")
.READ_ONLY,
0,
LOCAL.FileChannel.size()
)
) />
<cfset LOCAL.PDFPage = LOCAL.PDFFile.getPage(1) />
<cfif NOT StructKeyExists(LOCAL, "PDFPage")>
<cfthrow message="PDF cannot be converted - unknown error." />
</cfif>
<cfcatch type="Any">
<cfscript>
LOCAL.RandomAccessFile.close();
</cfscript>
<cfthrow message="PDF cannot be converted - unknown error." />
</cfcatch>
</cftry>
<cfscript>
// Create new image
LOCAL.Rectangle = LOCAL.PDFPage.getBBox();
LOCAL.BufferedImage =
CreateObject("java", "java.awt.image.BufferedImage")
.init(
LOCAL.Rectangle.width,
LOCAL.Rectangle.height,
CreateObject("java", "java.awt.image.BufferedImage")
.TYPE_INT_RGB
);
LOCAL.Graphics = LOCAL.BufferedImage.createGraphics();
LOCAL.Graphics.drawImage(
LOCAL.PDFPage.getImage(
LOCAL.Rectangle.width,
LOCAL.Rectangle.height,
LOCAL.Rectangle,
JavaCast("null", ""),
true,
true
),
0,
0,
JavaCast("null", "")
);
LOCAL.Graphics.dispose();
LOCAL.ImageFile =
CreateObject("java", "java.io.File")
.init(LOCAL.DestinationFilePath);
// Delete existing image file
if (LOCAL.ImageFile.exists())
LOCAL.ImageFile.delete();
// Export the image to the specified format
CreateObject("java", "javax.imageio.ImageIO")
.write(
LOCAL.BufferedImage,
JavaCast("string", Trim(ARGUMENTS.format)),
LOCAL.ImageFile
);
LOCAL.RandomAccessFile.close();
return LOCAL.DestinationFilePath;
</cfscript>
</cffunction>
REQUEST.UDFLib.Image:
<cffunction name="scale" returntype="Any" output="false">
<cfargument name="imagePath" type="String" required="true" />
<cfargument name="action" type="String" default="fit" hint="shrink, enlarge, or fit"/>
<cfargument name="minWidth" type="Numeric" default="-1" />
<cfargument name="minHeight" type="Numeric" default="-1" />
<cfargument name="maxWidth" type="Numeric" default="-1" />
<cfargument name="maxHeight" type="Numeric" default="-1" />
<cfscript>
var scaledDimensions = {
width = -1,
height = -1
};
var scaledImage = ImageNew();
scaledImage = ImageNew(ARGUMENTS.imagePath);
switch (ARGUMENTS.action) {
case "shrink":
scaledDimensions =
getDimensionsToShrink(
imageHeight = scaledImage.getHeight(),
imageWidth = scaledImage.getWidth(),
maxWidth = ARGUMENTS.maxWidth,
maxHeight = ARGUMENTS.maxHeight
);
break;
case "enlarge":
scaledDimensions =
getDimensionsToEnlarge(
imageHeight = scaledImage.getHeight(),
imageWidth = scaledImage.getWidth(),
minWidth = ARGUMENTS.minWidth,
minHeight = ARGUMENTS.minHeight
);
break;
default:
scaledDimensions =
getDimensionsToFit(
imageHeight = scaledImage.getHeight(),
imageWidth = scaledImage.getWidth(),
minWidth = ARGUMENTS.minWidth,
minHeight = ARGUMENTS.minHeight,
maxWidth = ARGUMENTS.maxWidth,
maxHeight = ARGUMENTS.maxHeight
);
break;
}
if (scaledDimensions.width > 0 && scaledDimensions.height > 0) {
// This helps the image quality
ImageSetAntialiasing(scaledImage, "on");
ImageScaleToFit(
scaledImage,
scaledDimensions.width,
scaledDimensions.height
);
}
return scaledImage;
</cfscript>
</cffunction>
Thanks to @MarkAKruger for pointing me to CFROOT\runtime\bin\hs_err_pid*.log files. It looks like a memory issue when trying to convert the PDF to PNG....
Here is a link to the contents of the file from the last time I tried to run this template (to large to include here):
I would still really appreciate any help figuring out how to fix.....
Take a look in the /runtime/bin directory and see if you hav esome error files - something like hserrorxxxx.log (don't recall the format for java 1.4). This is a "hotspot" error - typically generated on a crash. Open one up and take a look. My guess is you are either running out of memory or there is an RGB image embedded in your PDF that is abending your server. You may be able to figure it out from the stack in the hs (hotspot) error file.