Skip to main content
Ben Nadel at cf.Objective() 2017 (Washington, D.C.) with: Jeremy Wight
Ben Nadel at cf.Objective() 2017 (Washington, D.C.) with: Jeremy Wight

Listing All Classes In A Jar File Using ColdFusion

By
Published in Comments (5)

You'll probably never need to do this, but today, I needed to find out what Java classes were available in a given JAR file using ColdFusion. The reason - I was doing some work on my POI Utility ColdFusion custom tags and I needed to see if the version of the POI JAR that ships with ColdFusion supports certain classes. Turns out, this is a fairly straightforward task. I wrapped the functionality up in a ColdFusion user defined function that takes the expanded path to the target JAR file:

<cffunction
	name="GetJarClasses"
	access="public"
	returntype="array"
	output="false"
	hint="I return an array of classes in the given JAR file (expanded path).">

	<!--- Define arguments. --->
	<cfargument
		name="JarFilePath"
		type="string"
		required="true"
		hint="I am the expanded path of the JAR file."
		/>

	<!--- Define the local scope. --->
	<cfset var LOCAL = {} />

	<!--- Create a default array of classes. --->
	<cfset LOCAL.Classes = [] />


	<!---
		Create a JAR input stream to read in the line items
		from our target JAR file.
	--->
	<cfset LOCAL.JarFile = CreateObject(
		"java",
		"java.util.jar.JarInputStream"
		).Init(

			CreateObject(
				"java",
				"java.io.FileInputStream"
				).Init(

					JavaCast(
						"string",
						ARGUMENTS.JarFilePath
						)
				)
			)
		/>


	<!---
		Now that we have our JAR file input stream, let's loop
		over all the entries looking for CLASS files.
	--->
	<cfloop condition="true">

		<!---
			Get the next entry. This might return NULL if the
			JAR file has no more classes.
		--->
		<cfset LOCAL.JarEntry = LOCAL.JarFile.GetNextJarEntry() />

		<!---
			Check to see if the entry variable exists. If it
			does not, then it means the JAR file return NULL
			and we are done finding classes.
		--->
		<cfif StructKeyExists( LOCAL, "JarEntry" )>

			<!---
				Check to make sure that this entry is not a
				directory, but is, in fact a class.
			--->
			<cfif REFindNoCase( "\.class$", LOCAL.JarEntry.GetName() )>

				<!---
					Add this class to the array. Since the JAR
					file really has a directory structure, let's
					replace the path separators with dots.
				--->
				<cfset LOCAL.ClassName = REReplace(
					LOCAL.JarEntry.GetName(),
					"[\\/]",
					".",
					"all"
					) />

				<!--- Strip off the ".class" path item. --->
				<cfset LOCAL.ClassName = REReplaceNoCase(
					LOCAL.ClassName,
					"\.class$",
					"",
					"one"
					) />

				<!--- Add the formatted class name. --->
				<cfset ArrayAppend(
					LOCAL.Classes,
					LOCAL.ClassName
					) />

			</cfif>

		<cfelse>

			<cfbreak />

		</cfif>

	</cfloop>


	<!--- Return the array of classes. --->
	<cfreturn LOCAL.Classes />
</cffunction>

To call it, you just do this (I had a copy of the installed POI JAR file in the same directory as my test file):

<!--- Get file path to POI installed JAR file. --->
<cfset strJarFilePath = ExpandPath(
	"./poi-2.5.1-final-20040804.jar"
	) />

<!--- Output the classes. --->
<cfdump
	var="#GetJarClasses( strJarFilePath )#"
	label="POI 2.5.1 Final Classes"
	/>

Running this, we get an array with the following values (abbreviated):

org.apache.poi.ddf.DefaultEscherRecordFactory
org.apache.poi.ddf.EscherArrayProperty
org.apache.poi.ddf.EscherBSERecord
org.apache.poi.ddf.EscherBlipRecord
..... several hundred classes .....
org.apache.poi.util.ShortList
org.apache.poi.util.StringUtil
org.apache.poi.util.SystemOutLogger

Anyway, just thought I would post that in case anyone ever needs this kind of functionality.

Want to use code from this post? Check out the license.

Reader Comments

32 Comments

I never really play around with JAR files much, so this comment could be totally off base, but, could you have not just used the cfzip tag? It accepts a JAR file and you could use the list action and just dumped that out, right? or am i missing the point? It's Friday so my brain has shut of ffor the weekend :-)

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel