<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: Java classpath and directories</title>
	<atom:link href="http://vafer.org/blog/20081203024812/feed" rel="self" type="application/rss+xml" />
	<link>http://vafer.org/blog/20081203024812</link>
	<description>ramblings of a creative mind</description>
	<lastBuildDate>Sun, 07 Mar 2010 01:54:16 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Thilina Mahesh Buddhika</title>
		<link>http://vafer.org/blog/20081203024812/comment-page-1#comment-59137</link>
		<dc:creator>Thilina Mahesh Buddhika</dc:creator>
		<pubDate>Sat, 18 Apr 2009 19:16:29 +0000</pubDate>
		<guid isPermaLink="false">http://vafer.org/blog/?p=723#comment-59137</guid>
		<description>hi,

This is a saviour. 

thanks.

/thilina</description>
		<content:encoded><![CDATA[<p>hi,</p>
<p>This is a saviour. </p>
<p>thanks.</p>
<p>/thilina</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: TheGuru</title>
		<link>http://vafer.org/blog/20081203024812/comment-page-1#comment-59066</link>
		<dc:creator>TheGuru</dc:creator>
		<pubDate>Mon, 19 Jan 2009 23:42:51 +0000</pubDate>
		<guid isPermaLink="false">http://vafer.org/blog/?p=723#comment-59066</guid>
		<description>Sounds like the whole classpath thing in java needs a rewrite/enhancement and transformed from being a simple search path directive into some sort of resource catalog e.g. classpath.xml</description>
		<content:encoded><![CDATA[<p>Sounds like the whole classpath thing in java needs a rewrite/enhancement and transformed from being a simple search path directive into some sort of resource catalog e.g. classpath.xml</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Steve</title>
		<link>http://vafer.org/blog/20081203024812/comment-page-1#comment-59053</link>
		<dc:creator>Steve</dc:creator>
		<pubDate>Fri, 09 Jan 2009 16:23:25 +0000</pubDate>
		<guid isPermaLink="false">http://vafer.org/blog/?p=723#comment-59053</guid>
		<description>Hello,
I am wondering what will happen if I would like to use jar files and directories too in the classpath like this:

java -classpath ../lib/&#039;*&#039;;resources/xml;&#039;.&#039; com.myapp.MainClass

And the MainClass is a separate class file which can accessible from the current directory (&#039;.&#039;) and not part of the jar file.

Is this will work?
Thank you.</description>
		<content:encoded><![CDATA[<p>Hello,<br />
I am wondering what will happen if I would like to use jar files and directories too in the classpath like this:</p>
<p>java -classpath ../lib/&#8217;*';resources/xml;&#8217;.&#8217; com.myapp.MainClass</p>
<p>And the MainClass is a separate class file which can accessible from the current directory (&#8217;.') and not part of the jar file.</p>
<p>Is this will work?<br />
Thank you.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: TheGuru</title>
		<link>http://vafer.org/blog/20081203024812/comment-page-1#comment-59029</link>
		<dc:creator>TheGuru</dc:creator>
		<pubDate>Mon, 15 Dec 2008 00:57:12 +0000</pubDate>
		<guid isPermaLink="false">http://vafer.org/blog/?p=723#comment-59029</guid>
		<description>More often than not one uses a script to construct the CLASSPATH, but what typically happens in the software development cycle is that slowly more tools, components, re-use, 3rd party products are introduced and the script automatically grows the CLASSPATH size to beyond the limit of either the LINE_SIZE or the memory size for shell variables depending on chosen implementation. Worse still, the architects who design the solution are often unaware of this silly (old) limitation. And worse again is that a lot of jars (e.g. commons) are often repeated between different 3rd party products and the script is often not smart enough to know that. And even worse again, when the application is delivered to the customer the whole application ends up being managed by some 3rd party JMX instrumenting management/framework tool that pre-pends its own CLASSPATH to the existing one.  

The disingenuous ways to crunch a CLASSPATH are.
1) use symlinks e.g. ln -s /reallyannoyinglong3rdpartysoftwarepath2libdir /s1 
2) use dos SUBST command e.g. SUBST J: C:\reallyannoyinglong3rdpartysoftwarepath2libdir
3) The following is dangerous, but can work when you know the products well.
unjar all jars to a temp dir and jar them up as one jar file e.g. annoyinglybig3pp.jar
4) Manually go through all jars of all 3rd party products and grow old figuring out what you don&#039;t use and somehow exclude it.
5) Use a special shell or modify an existing one to cater for huge line or environment variable sizes.
6) Incorporate some class loading facility within the running application itself.

ALL THE ABOVE INTRODUCE MAINTENANCE CONCERNS OVER AND ABOVE NORMAL OPERATIONS.

Thanks to this blog I now can use the escaped wildcard, but even better can use an application Manifest, but does anyone know if there is a limit to the size of the Class-Path: line in a Manifest file?

The Manifest/Class-Path approach seems to imply that an app delivered with lots of lib/jars can be started by simply specifying the jar that has the full app Class-Path defined in its manifest. E.g. &quot;java -cp /app1/lib/start_app1.jar app1.Main&quot;

I assume that if I&#039;m using two 3rd party apps (app1 and app2) in my application (myapp) I should be able to create a trivial startup jar for each app using the above Manifest/Class-Path technique and run it as follows 
E.g. &quot;java -cp /myapp/start_myapp.jar:/app1/lib/start_app1.jar:/app2/lib/start_app2.jar myapp.Main&quot;

If this works then this is great at solving the long CLASSPATH issue (and the spec says you can use the wildcard in the Manifest/Class-Path as well), but stay with me because I&#039;m now going to present a java problem that has bothered me at times.

When your application uses many external software components, then inside these external components may be common libraries that are at different revision levels. The first one that comes to mind is log4j. The developers of these external software components only think that you will be using the version that they supplied, however that particular version may interfere with other external software components when you put it at the start of the CLASSPATH. So you stick the newer version of log4j at the start of the CLASSPATH and you solve one problem but break something else. Unfortunately you don&#039;t own the external software and cannot apply a fix/update as it is part of a bigger software baseline. This is very unlike internal software component dependencies where you have better control and can use neat tools like IVY for managing them.

However, if I were to use the Manifest/Class-Path approach and create trivial start_app jars for each app as before, is the class loader able to construct an internal search path that allows the correct use of the right version of log4j jar for the right app? That is, is there some internal search path group hierarchy that can be constructed using the above Manifest/Class-Path technique? My gut feeling is no.

Would it be a good idea for java to facilitate some form of internal search path group hierarchy when it comes to searching for classes, other than just the URL/directory path, for the specific purpose of solving dependency issues when using common family components of varying revisions across many external apps?
Using the Manifest/Class-Path technique to specify a group CLASSPATH to me seems like a good place to control this group search hierarchy, so when a class is requested by a running application the search is first performed in the local group hashtable for that class and if not found then the rest of the class hashtable is searched. I don’t think it would add too much of a runtime overhead as the whole class list is only searched once (in 2 steps that can even be run in parallel).

Unfortunately I no longer have a need to test this because I no longer work in a place that uses a horrendously complex mix of software suites (i.e. telco), but would still appreciate the feedback.</description>
		<content:encoded><![CDATA[<p>More often than not one uses a script to construct the CLASSPATH, but what typically happens in the software development cycle is that slowly more tools, components, re-use, 3rd party products are introduced and the script automatically grows the CLASSPATH size to beyond the limit of either the LINE_SIZE or the memory size for shell variables depending on chosen implementation. Worse still, the architects who design the solution are often unaware of this silly (old) limitation. And worse again is that a lot of jars (e.g. commons) are often repeated between different 3rd party products and the script is often not smart enough to know that. And even worse again, when the application is delivered to the customer the whole application ends up being managed by some 3rd party JMX instrumenting management/framework tool that pre-pends its own CLASSPATH to the existing one.  </p>
<p>The disingenuous ways to crunch a CLASSPATH are.<br />
1) use symlinks e.g. ln -s /reallyannoyinglong3rdpartysoftwarepath2libdir /s1<br />
2) use dos SUBST command e.g. SUBST J: C:\reallyannoyinglong3rdpartysoftwarepath2libdir<br />
3) The following is dangerous, but can work when you know the products well.<br />
unjar all jars to a temp dir and jar them up as one jar file e.g. annoyinglybig3pp.jar<br />
4) Manually go through all jars of all 3rd party products and grow old figuring out what you don&#8217;t use and somehow exclude it.<br />
5) Use a special shell or modify an existing one to cater for huge line or environment variable sizes.<br />
6) Incorporate some class loading facility within the running application itself.</p>
<p>ALL THE ABOVE INTRODUCE MAINTENANCE CONCERNS OVER AND ABOVE NORMAL OPERATIONS.</p>
<p>Thanks to this blog I now can use the escaped wildcard, but even better can use an application Manifest, but does anyone know if there is a limit to the size of the Class-Path: line in a Manifest file?</p>
<p>The Manifest/Class-Path approach seems to imply that an app delivered with lots of lib/jars can be started by simply specifying the jar that has the full app Class-Path defined in its manifest. E.g. &#8220;java -cp /app1/lib/start_app1.jar app1.Main&#8221;</p>
<p>I assume that if I&#8217;m using two 3rd party apps (app1 and app2) in my application (myapp) I should be able to create a trivial startup jar for each app using the above Manifest/Class-Path technique and run it as follows<br />
E.g. &#8220;java -cp /myapp/start_myapp.jar:/app1/lib/start_app1.jar:/app2/lib/start_app2.jar myapp.Main&#8221;</p>
<p>If this works then this is great at solving the long CLASSPATH issue (and the spec says you can use the wildcard in the Manifest/Class-Path as well), but stay with me because I&#8217;m now going to present a java problem that has bothered me at times.</p>
<p>When your application uses many external software components, then inside these external components may be common libraries that are at different revision levels. The first one that comes to mind is log4j. The developers of these external software components only think that you will be using the version that they supplied, however that particular version may interfere with other external software components when you put it at the start of the CLASSPATH. So you stick the newer version of log4j at the start of the CLASSPATH and you solve one problem but break something else. Unfortunately you don&#8217;t own the external software and cannot apply a fix/update as it is part of a bigger software baseline. This is very unlike internal software component dependencies where you have better control and can use neat tools like IVY for managing them.</p>
<p>However, if I were to use the Manifest/Class-Path approach and create trivial start_app jars for each app as before, is the class loader able to construct an internal search path that allows the correct use of the right version of log4j jar for the right app? That is, is there some internal search path group hierarchy that can be constructed using the above Manifest/Class-Path technique? My gut feeling is no.</p>
<p>Would it be a good idea for java to facilitate some form of internal search path group hierarchy when it comes to searching for classes, other than just the URL/directory path, for the specific purpose of solving dependency issues when using common family components of varying revisions across many external apps?<br />
Using the Manifest/Class-Path technique to specify a group CLASSPATH to me seems like a good place to control this group search hierarchy, so when a class is requested by a running application the search is first performed in the local group hashtable for that class and if not found then the rest of the class hashtable is searched. I don’t think it would add too much of a runtime overhead as the whole class list is only searched once (in 2 steps that can even be run in parallel).</p>
<p>Unfortunately I no longer have a need to test this because I no longer work in a place that uses a horrendously complex mix of software suites (i.e. telco), but would still appreciate the feedback.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: M. A. Sridhar</title>
		<link>http://vafer.org/blog/20081203024812/comment-page-1#comment-59028</link>
		<dc:creator>M. A. Sridhar</dc:creator>
		<pubDate>Fri, 12 Dec 2008 18:21:07 +0000</pubDate>
		<guid isPermaLink="false">http://vafer.org/blog/?p=723#comment-59028</guid>
		<description>If you&#039;re running on linux, you can use the find and shell features to achieve this goal:

java -classpath `find jarsDir -name &#039;*.jar&#039; &#124; sed -e &#039;s/ /:/g&#039;` Main

The find command produces all .jar files anywhere in the jarsDir directory, separated by spaces, and the sed command replaces spaces with colons, as needed by the classpath variable.</description>
		<content:encoded><![CDATA[<p>If you&#8217;re running on linux, you can use the find and shell features to achieve this goal:</p>
<p>java -classpath `find jarsDir -name &#8216;*.jar&#8217; | sed -e &#8217;s/ /:/g&#8217;` Main</p>
<p>The find command produces all .jar files anywhere in the jarsDir directory, separated by spaces, and the sed command replaces spaces with colons, as needed by the classpath variable.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Ron</title>
		<link>http://vafer.org/blog/20081203024812/comment-page-1#comment-59027</link>
		<dc:creator>Ron</dc:creator>
		<pubDate>Thu, 11 Dec 2008 15:31:21 +0000</pubDate>
		<guid isPermaLink="false">http://vafer.org/blog/?p=723#comment-59027</guid>
		<description>On Linux, the script to add the jars in a certain directory is fairly simple...not quite so clean in Windows batch files. Could probably use Powershell, but I dug this up from the site listed below and adapted it for our use. It works. BTW, thanks for the Java6 tip! 

http://www.artima.com/forums/flat.jsp?forum=1&amp;thread=120583

setLocal EnableDelayedExpansion 
set JarsDir=somedirectory\lib
if defined classpath (set classpath=%classpath%;.) else (set classpath=.)
for %%i in (&quot;%JarsDir%\*.jar&quot;) do set classpath=!classpath!;%%i
endlocal &amp; set classpath=%classpath% 
set classpath=%CLASSPATH%
echo %CLASSPATH%</description>
		<content:encoded><![CDATA[<p>On Linux, the script to add the jars in a certain directory is fairly simple&#8230;not quite so clean in Windows batch files. Could probably use Powershell, but I dug this up from the site listed below and adapted it for our use. It works. BTW, thanks for the Java6 tip! </p>
<p><a href="http://www.artima.com/forums/flat.jsp?forum=1&amp;thread=120583" rel="nofollow">http://www.artima.com/forums/flat.jsp?forum=1&amp;thread=120583</a></p>
<p>setLocal EnableDelayedExpansion<br />
set JarsDir=somedirectory\lib<br />
if defined classpath (set classpath=%classpath%;.) else (set classpath=.)<br />
for %%i in (&#8221;%JarsDir%\*.jar&#8221;) do set classpath=!classpath!;%%i<br />
endlocal &amp; set classpath=%classpath%<br />
set classpath=%CLASSPATH%<br />
echo %CLASSPATH%</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Caligula</title>
		<link>http://vafer.org/blog/20081203024812/comment-page-1#comment-59023</link>
		<dc:creator>Caligula</dc:creator>
		<pubDate>Thu, 11 Dec 2008 10:19:12 +0000</pubDate>
		<guid isPermaLink="false">http://vafer.org/blog/?p=723#comment-59023</guid>
		<description>@Tony: Sure, but sometimes that isn&#039;t what you need, like if you&#039;re running a JRuby REPL into some components of a web app--so you need all of Hibernate, your domain objects, JDBC driver, etc. Setting the classpath on the command line or a script is the only practical way to do that, other than creating a JAR that starts the REPL and has the (possibly changing) library requirements in the manifest.</description>
		<content:encoded><![CDATA[<p>@Tony: Sure, but sometimes that isn&#8217;t what you need, like if you&#8217;re running a JRuby REPL into some components of a web app&#8211;so you need all of Hibernate, your domain objects, JDBC driver, etc. Setting the classpath on the command line or a script is the only practical way to do that, other than creating a JAR that starts the REPL and has the (possibly changing) library requirements in the manifest.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: /dev/Kico &#187; Blog Archive &#187; Java: Algo sobre o classpath que eu não sabia (e talvez você também não)</title>
		<link>http://vafer.org/blog/20081203024812/comment-page-1#comment-59022</link>
		<dc:creator>/dev/Kico &#187; Blog Archive &#187; Java: Algo sobre o classpath que eu não sabia (e talvez você também não)</dc:creator>
		<pubDate>Thu, 11 Dec 2008 10:15:02 +0000</pubDate>
		<guid isPermaLink="false">http://vafer.org/blog/?p=723#comment-59022</guid>
		<description>[...] com este post, no qual é mencionada uma novidade do Java 6 que não conhecia: você agora pode usar caracteres [...]</description>
		<content:encoded><![CDATA[<p>[...] com este post, no qual é mencionada uma novidade do Java 6 que não conhecia: você agora pode usar caracteres [...]</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: tcurdt</title>
		<link>http://vafer.org/blog/20081203024812/comment-page-1#comment-59019</link>
		<dc:creator>tcurdt</dc:creator>
		<pubDate>Wed, 10 Dec 2008 16:39:45 +0000</pubDate>
		<guid isPermaLink="false">http://vafer.org/blog/?p=723#comment-59019</guid>
		<description>Uuuh - nice! I didn&#039;t know you can do that! Thanks, Tony!</description>
		<content:encoded><![CDATA[<p>Uuuh &#8211; nice! I didn&#8217;t know you can do that! Thanks, Tony!</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Tony</title>
		<link>http://vafer.org/blog/20081203024812/comment-page-1#comment-59018</link>
		<dc:creator>Tony</dc:creator>
		<pubDate>Wed, 10 Dec 2008 16:34:59 +0000</pubDate>
		<guid isPermaLink="false">http://vafer.org/blog/?p=723#comment-59018</guid>
		<description>Good info, but, as I code for the lowest release of Java 5, it wont help me. However just one thing.... Ewwww!!

I never have a .bat / .sh file to launch my java code.  Instead, I store the classpath in the main .jar&#039;s manifest, the .jar with the class that contains the &#039;public static void main(args[]s)&#039; . Somewhat like this:

Manifest-Version: 1.0
Main-Class: com.test.Launcher
Class-Path: 
 jcifs.jar 
 jt400.jar 
 swingx.jar 
 swixml.jar 
 tonytools.jar 
 jdom.jar 
 TimingFramework.jar 


Just ensure that each jar file has a space before and after on each line. Once done this way, The java application can be launched by using java -jar {mainjar}.jar , or even just double clicking from the desktop.

Much easier, and more cross platform compatable (no .bat for windows, .sh for OS X, etc.)</description>
		<content:encoded><![CDATA[<p>Good info, but, as I code for the lowest release of Java 5, it wont help me. However just one thing&#8230;. Ewwww!!</p>
<p>I never have a .bat / .sh file to launch my java code.  Instead, I store the classpath in the main .jar&#8217;s manifest, the .jar with the class that contains the &#8216;public static void main(args[]s)&#8217; . Somewhat like this:</p>
<p>Manifest-Version: 1.0<br />
Main-Class: com.test.Launcher<br />
Class-Path:<br />
 jcifs.jar<br />
 jt400.jar<br />
 swingx.jar<br />
 swixml.jar<br />
 tonytools.jar<br />
 jdom.jar<br />
 TimingFramework.jar </p>
<p>Just ensure that each jar file has a space before and after on each line. Once done this way, The java application can be launched by using java -jar {mainjar}.jar , or even just double clicking from the desktop.</p>
<p>Much easier, and more cross platform compatable (no .bat for windows, .sh for OS X, etc.)</p>
]]></content:encoded>
	</item>
</channel>
</rss>
