Question

Locate Properties File Inside Jar During Junit Tests with Ant

Asked by: cbuch

I am having problems running my Junit tests via Ant. I can't seem to get Ant to see the properties file it needs to load a dll my project needs. All my tests work using the Junit GUI in Elcipse, so I'm pretty sure it's not a problem with the tests themselves. I think my problem is something classpath-related, but I can't seem to find the problem.

jar strucure: /root/folder/../Foo.properties

I could really use a second set of eyes, so any help is appreciated. Thanks in advance!

--Charly

This is how the properties file is loaded in the library:
 
 
// load class properties
props = PropertyLoader.loadProperties(Foo.class);
 
public static Properties loadProperties(Class className) {
    return loadProperties(className.getName());
}
 
public static Properties loadProperties(final String propsName) {
    Properties props = null;
    InputStream in = null;
    try {
      ClassLoader cl = ClassLoader.getSystemClassLoader();
      String name = propsName.replace('.', '/').concat(".properties");
 
      in = cl.getResourceAsStream(name);
      if (in != null) {
        props = new Properties();
        props.load(in);
      }
    }
    catch (Exception e) {
      props = null;
    }
    finally {
      if (props == null) {
        System.err.print("Property file " + propsName + " doesn't exist. System terminated.");
        System.exit(0);
      }
    }
 
    return props;
  }
 
 
Except from build file in question:
 
 
<!-- Pattern of source files to copy into classpath-->
    <property name="source.files.tocopy"
        value="**/*.properties,**/*.dtd,**/*.xml,**/*.jpg" />
 
    <path id="compile.classpath">
        <fileset dir="lib">
                <include name="*.jar" />
        </fileset>
    </path>
 
    <!-- Generate Class-Path entry for the JAR's Manifest -->
    <pathconvert property="manifest.classpath" 
        pathsep=" " dirsep="\">
        <map from="${basedir}/" to="" />
        <fileset dir="lib">
                <include name="*.jar" />
        </fileset>
    </pathconvert>
 
    <!-- Run tests against the JAR -->
    <path id="test.compile.classpath">
        <path refid="compile.classpath" />
        <pathelement location="${target.jar}" />
    </path>
 
    <path id="test.classpath">
        <path refid="test.compile.classpath" />
        <pathelement location="${test.classes.dir}" />
    </path>
 
 
 
    <!-- - - - - - - - - - - - - - - - - - 
          target: test-compile                      
         - - - - - - - - - - - - - - - - - -->
    <target name="test-compile" depends="compile, test-init"
        description="Compiles our testing code">
 
        <javac destdir="${test.classes.dir}"
                        debug="true"
                        includeAntRuntime="true"
                        srcdir="test">
                <classpath refid="test.compile.classpath" />
        </javac>
 
        <copy todir="${test.classes.dir}">
                <fileset dir="test" includes="${source.files.tocopy}"/>
                <fileset dir="resources" includes="${source.files.tocopy}"/>
        </copy>
 
    </target>
 
 
    <!-- ================================= 
          target: test              
         ================================= -->
    <target name="test" depends="test-compile, optional-tests">
 
        <description>
                Runs our tests, generates reports, and stops 
                the build on failure.  Optionally runs one test.
        </description>
 
        <junit printsummary="false" 
                errorProperty="test.failed" 
                failureProperty="test.failed">
                <classpath>
                        <path refid="test.classpath" />
                </classpath>                    
                <sysproperty key="test.properties" value="${test.properties.file}"/>
                <formatter type="brief" usefile="false" />
                <formatter type="xml" />
                <test name="${testcase}" todir="${test.data.dir}" if="testcase" />
                <batchtest todir="${test.data.dir}" unless="testcase">
                        <fileset dir="${test.classes.dir}">
                                <patternset>
                                        <include name="**/test/*Test.class" />
                                        <exclude name="**/test/*Printer*.class" unless="test.properties.file" />
                                </patternset>
                        </fileset>
                </batchtest>
        </junit>

                                  
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:

Select allOpen in new window

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
2008-12-07 at 17:03:53ID23964772
Tags

Ant 1.7.1

,

Java 6

,

Junit 3

,

Eclipse 3.3.1

Topics

ANT

,

Java Programming Language

,

Eclipse

Participating Experts
2
Points
500
Comments
34

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. Eclipse & ANT Classpath
    I'm trying to use ANT to build my eclipse project and having problems which look like they're classpath related. I've set the classpath for the project and it appears to be fine when I'm editing it ( none of the import statements are errored and all the classes which are in t...
  2. Problems with Ant, jar and classpath
    Hi, Initially I had 1 jar file (classes12.jar) in the classpath (see below) and it worked fine. Then I added another jar file (log4j.jar), but I when I run this, it gives me NoClassDefFoundError for the log4j references. The new log4j.jar is in the same directory as classes...
  3. jar of a jar
    Hi all, I have a list of jar files that I have to include in my classpath: Ex: java -classpath "dd.jar;ddr.jar" mytest The problem is that the list of jar files are getting too long. Could I Jar all these files in one jar file. If Yes please provide me with the way...
  4. Ant
    Hello, I have one non-web based application. I have the Ant file to create the jar file. I have another web application that uses this jar. My client would like them to be in single codebase and one Ant file so that we can identify whether to build the jar or war file so al...

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: objectsPosted on 2008-12-07 at 18:07:26ID: 23118356

Are your properties files being copied correctly into the directory in your classpath?

 

by: objectsPosted on 2008-12-07 at 18:09:00ID: 23118359

>       String name = propsName.replace('.', '/').concat(".properties");

that doesn't look right to me.
resource names are not paths.

 

by: cbuchPosted on 2008-12-07 at 18:58:00ID: 23118508

I looked at the jar file I am building and it's folder structure is exactly the same as where I am copying it.  In my compile target, I am taking all the files in my resources directory and copying them over to my build/classes directory with their folder structure intact.  

When I build the jar manually and run it, it is able to find the properties file without problems.  It just seems like while I am running everything in Ant that I get into problems.

I looked over that string manipulation part as well, and it looks like the original author was translating the fully qualified class name into a folder hierarchy, and tacking on a ".properties" at the end like so:

foo.bar.SomeClass

turns into

foo/bar/SomeClass.properties

It seems to work for the most part, but I'm thinking that is part of my problem.  The author was banking on the fact that the folder structure was going to be exactly the same as the class name right off the root directory.  It seems to work for the usual case, but is inflexible.

My most recent line of thought on this is that the root folder where the unit tests are being run at in Ant has an extra directory or two at the top?  So when it looks for /foo/bar/SomeClass.properties it is finding classes/foo/bar/SomeClass.properties.

Just in case I am omitting something you need, I will include the entire build file below. Thanks for helping me.

--Charly

<?xml version="1.0"?>
<project name="label-server">
 
	<description>
		This build file compiles, tests, and packages our 
		label-server application.
	</description>
	
	<!-- Property Override Point -->
	<property file="build.properties"/>
 
	<property name="build.dir" location="build" />
	<property name="build.classes.dir" location="${build.dir}/classes" />
 
	<!-- Testing -->
<!--	<property name="test.dir" location="${build.dir}/test" />-->
	<property name="test.dir" location="${build.dir}" />
	<property name="test.classes.dir" location="${test.dir}/classes" />
	<property name="test.data.dir" location="${test.dir}/data" />
	<property name="test.reports.dir" location="${test.dir}/reports" />
 
	<!-- Distribution -->
	<property name="dist.dir" location="dist" />
	<property name="dist.javadoc.dir" location="${dist.dir}/javadoc" />
	<property name="dist.lib.dir" location="${dist.dir}/lib"/>
	<property name="dist.doc.dir" location="${dist.dir}/docs" />
 
	<!-- Project / Target Naming -->
	<property name="project.name" value="${ant.project.name}" />
	<property name="project.version" value="2.1" />
	<property name="project.name-ver" value="${project.name}-${project.version}" />
	<property name="target.name" value="${project.name-ver}.jar" />
	<property name="target.jar" location="${dist.dir}/${target.name}" />
 
	<!-- Distributables -->
	<property name="target.zip" location="${dist.dir}/${project.name-ver}.zip" />
	<property name="src.zip" location="${dist.dir}/${project.name-ver}-src.zip" />
 
	<!-- Generate Timestamp -->
	<tstamp>
		<format property="timestamp" pattern="yyyy-mm-dd HH:mm:ss" locale="en" />
	</tstamp>
	
	<!-- Library Website References -->
	<property name="java.homepage" value="www.java.com/getjava"/>
	<property name="eclipse.homepage" value="www.eclipse.org"/>
	<property name="ant.homepage" value="ant.apache.org"/>
	<property name="commons.lang.homepage" value="commons.apache.org/lang"/>
	<property name="log4j.homepage" value="logging.apache.org/log4j"/>
	<property name="junit.homepage" value="www.junit.org"/>
	<property name="gsbase.homepage" value="sourceforge.net/projects/gsbase"/>
	<property name="jdom.homepage" value="www.jdom.org"/>
	<property name="jeasyopc.homepage" value="sourceforge.net/projects/jeasyopc"/>
	<property name="junitaddons.homepage" value="junit-addons.sourceforge.net"/>
	<property name="filemonitor.homepage" value="geosoft.no/software/filemonitor/FileMonitor.java.html"/>
	
	<!-- Other Website References -->
	<property name="java.help.install" value="java.sun.com/javase/6/webnotes/install/jdk/install-windows.html"/>
	<property name="java.help.filenames" value="java.sun.com/javase/6/docs/api/java/io/File.html"/>
	
	<!-- Pattern of source files to copy into classpath-->
	<property name="source.files.tocopy"
		value="**/*.properties,**/*.dtd,**/*.xml,**/*.jpg" />
 
	<!-- Executable JAR Info -->
	<property name="main.class" value="foo.bar.ClassWithMain" />
	<property name="jar.compress" value="false"/>
 
	<path id="compile.classpath">
		<fileset dir="lib">
			<include name="*.jar" />
		</fileset>
	</path>
 
	<!-- Generate Class-Path entry for the JAR's Manifest -->
	<pathconvert property="manifest.classpath" 
		pathsep=" " dirsep="\">
		<map from="${basedir}/" to="" />
		<fileset dir="lib">
			<include name="*.jar" />
		</fileset>
	</pathconvert>
 
	<!-- Run tests against the JAR -->
	<path id="test.compile.classpath">
		<path refid="compile.classpath" />
		<pathelement location="${target.jar}" />
	</path>
 
	<path id="test.classpath">
		<path refid="test.compile.classpath" />
		<pathelement location="${test.classes.dir}" />
	</path>
 
	<!-- Configuration Files -->
	<property name="config.file" location="labelingConfig.xml"/>
	<basename property="config.filename" file="${config.file}"/>
	<property name="config.overwrite" value="false" />
	<property name="logging.config" location="log4j.properties"/>
	<basename property="logging.config.name" file="${logging.config}"/>
	
	<!-- Unzip Location -->
	<property name="unzip.dir" location="${user.home}/Desktop/temp"/>
 
 
	<!-- ================================= 
          target: clean              
         ================================= -->
	<target name="clean" 
    	description="Deletes all files that are generated by the build.">
 
		<delete dir="${build.dir}"/>
		<delete dir="${dist.dir}"/>
 
	</target>
 
 
	<!-- - - - - - - - - - - - - - - - - - 
          target: init                      
         - - - - - - - - - - - - - - - - - -->
	<target name="init">
 
		<mkdir dir="${build.classes.dir}"/>
		<mkdir dir="${dist.dir}"/>
		<mkdir dir="${dist.javadoc.dir}"/>
		<mkdir dir="${dist.lib.dir}"/>
        <mkdir dir="${dist.doc.dir}"/>
 
	</target>
 
 
	<!-- ================================= 
          target: compile              
         ================================= -->
	<target name="compile" depends="init">
 
		<javac destdir="${build.classes.dir}" 
			debug="true" 
			srcdir="src">
			<classpath refid="compile.classpath" />
		</javac>
		
		<copy todir="${build.classes.dir}">
			<fileset dir="resources" includes="${source.files.tocopy}"/>
		</copy>
 
	</target>
 
 
	<!-- ================================= 
          target: package              
         ================================= -->
	<target name="package" depends="compile"
		description="Packages our project into an executable jar file.">
 
		<property name="manifest.mf" location="${build.dir}/manifest.mf" />
 
		<manifest file="${manifest.mf}">
			<attribute name="Built-By" value="${user.name}" />
			<attribute name="Built-On" value="${timestamp}" />
			<attribute name="Implementation-Title" value="Label Server" />
			<attribute name="Implementation-Version" value="${project.version}" />
			<attribute name="Main-Class" value="${main.class}" />
			<attribute name="Class-Path" value="${manifest.classpath}"/>
		</manifest>
 
		<jar destfile="${target.jar}" 
			compress="${jar.compress}" 
			duplicate="preserve" 
			manifest="${manifest.mf}">
			<fileset dir="${build.classes.dir}" />
		</jar>
 
	</target>
 
 
	<!-- - - - - - - - - - - - - - - - - - 
          target: test-init                      
         - - - - - - - - - - - - - - - - - -->
	<target name="test-init" depends="package">
 
		<mkdir dir="${test.classes.dir}" />
		<delete dir="${test.data.dir}" />
		<delete dir="${test.reports.dir}" />
		<mkdir dir="${test.data.dir}" />
		<mkdir dir="${test.reports.dir}" />
 
	</target>
 
 
	<!-- - - - - - - - - - - - - - - - - - 
          target: test-compile                      
         - - - - - - - - - - - - - - - - - -->
	<target name="test-compile" depends="compile, test-init"
		description="Compiles our testing code">
 
		<javac destdir="${test.classes.dir}"
				debug="true"
				includeAntRuntime="true"
				srcdir="test">
			<classpath refid="test.compile.classpath" />
		</javac>
 
		<copy todir="${test.classes.dir}">
			<fileset dir="test" includes="${source.files.tocopy}"/>
			<fileset dir="resources" includes="${source.files.tocopy}"/>
		</copy>
 
	</target>
 
 
	<!-- ================================= 
          target: test              
         ================================= -->
	<target name="test" depends="test-compile, optional-tests">
		
		<description>
			Runs our tests, generates reports, and stops 
			the build on failure.  Optionally runs one test.
		</description>
 
		<junit printsummary="false" 
			errorProperty="test.failed" 
			failureProperty="test.failed">
			<classpath>
				<path refid="test.classpath" />
			</classpath>			
			<sysproperty key="test.properties" value="${test.properties.file}"/>
			<formatter type="brief" usefile="false" />
			<formatter type="xml" />
			<test name="${testcase}" todir="${test.data.dir}" if="testcase" />
			<batchtest todir="${test.data.dir}" unless="testcase">
				<fileset dir="${test.classes.dir}">
					<patternset>
						<include name="**/test/*Test.class" />
						<exclude name="**/test/*Printer*.class" unless="test.properties.file" />
					</patternset>
				</fileset>
			</batchtest>
		</junit>
 
		<junitreport todir="${test.data.dir}">
			<fileset dir="${test.data.dir}">
				<include name="TEST-*.xml" />
			</fileset>
			<report format="frames" todir="${test.reports.dir}" />
		</junitreport>
 
		<fail if="test.failed">Tests failed. Check ${test.reports.dir}</fail>
 
	</target>
	
	
	<!-- - - - - - - - - - - - - - - - - - 
          target: optional-tests                      
         - - - - - - - - - - - - - - - - - -->
    <target name="optional-tests" unless="test.properties.file">
    	
    	<echo level="warning">For printer tests you must set the location of test.properties.file</echo>
    	<echo level="verbose">test.properties.file required properties:</echo>
    	<echo level="verbose">firstPrinter.name</echo>
    	<echo level="verbose">firstPrinter.nameHint.lowercase</echo>
    	<echo level="verbose">firstPrinter.nameHint.uppercase</echo>
    	<echo level="verbose">firstPrinter.nameHint.mixedcase</echo>
    	<echo level="verbose">secondPrinter.nameHint.lowercase</echo>
    		
    </target>
 
 
 
	<!-- - - - - - - - - - - - - - - - - - 
          target: javadocs                      
         - - - - - - - - - - - - - - - - - -->
	<target name="javadocs" depends="compile">
 
		<javadoc
    			access="private"
    			sourcepath="src"
    			destdir="${dist.javadoc.dir}"
    			packagenames="foo.*"
    			use="true"
    			version="true"
    			windowtitle="${ant.project.name}"
    			failonerror="true">
			<classpath refid="compile.classpath"/>
		</javadoc>
 
	</target>
 
 
	<!-- - - - - - - - - - - - - - - - - - 
          target: dist-docs                      
         - - - - - - - - - - - - - - - - - -->
	<target name="dist-docs">
 
		<!-- Create our ms-dos batch file for running the app -->
		<copy todir="${dist.dir}" overwrite="true">
			<fileset dir="docs" includes="**/*.bat" />
			<filterset>
				<filter token="DATE" value="${timestamp}" />
				<filter token="JAR-NAME" value="${target.name}" />
				<filter token="CONFIG-FILE" value="${config.filename}"/>
				<filter token="PROJ-NAME" value="${project.name}"/>
				<filter token="LOG4J-FILE" value="${logging.config.name}"/>
			</filterset>
		</copy>
		
		<!-- Create our readme file -->
		<copy todir="${dist.doc.dir}" overwrite="true">
			<fileset dir="docs" includes="**/*.txt" />
			<filterset>
				<filter token="DATE" value="${timestamp}" />
				<filter token="PROJ-NAME" value="${project.name}"/>
				<filter token="CONFIG-FILE" value="${config.filename}"/>
				<filter token="JAVAHOMEPAGE" value="${java.homepage}"/>
				<filter token="JAVAHELPINSTALL" value="${java.help.install}"/>
				<filter token="JAVAHELPFILENAMES" value="${java.help.filenames}"/>
				<filter token="ECLIPSEHOMEPAGE" value="${eclipse.homepage}"/>
				<filter token="ANTHOMEPAGE" value="${ant.homepage}"/>
				<filter token="COMMONSLANGHOMEPAGE" value="${commons.lang.homepage}"/>
				<filter token="LOG4JHOMEPAGE" value="${log4j.homepage}"/>
				<filter token="JUNITHOMEPAGE" value="${junit.homepage}"/>
				<filter token="GSBASEHOMEPAGE" value="${gsbase.homepage}"/>
				<filter token="JDOMHOMEPAGE" value="${jdom.homepage}"/>
				<filter token="JEASYOPCHOMEPAGE" value="${jeasyopc.homepage}"/>
				<filter token="JUNIT-ADDONSHOMEPAGE" value="${junitaddons.homepage}"/>
				<filter token="FILEMONITORHOMEPAGE" value="${filemonitor.homepage}"/>
			</filterset>
		</copy>
 
	</target>
 
 
	<!-- ================================= 
          target: dist              
         ================================= -->
<!--	<target name="dist" depends="test, javadocs, dist-docs"-->
	<target name="dist" depends="javadocs, dist-docs"
    	description="Creates the distributable.">
 
		<!-- Copy over sample config file -->
		<copy file="${config.file}" todir="${dist.dir}" overwrite="${config.overwrite}"/>
		
		<!-- Copy over our log4j.properties file -->
		<copy file="${logging.config}" todir="${dist.dir}" overwrite="${config.overwrite}"/>
 
		<!-- Copy over our library -->
		<copy todir="${dist.lib.dir}">
			<fileset dir="lib">
				<include name="*.jar" />
				<include name="*.dll" />
			</fileset>
		</copy>
 
		<!-- Can't figure out how to reference xsd inside jar file -->
		<copy todir="${dist.lib.dir}" flatten="true">
			<fileset dir="resources">
				<include name="**/*.xsd"/>
			</fileset>
		</copy>
 
	</target>
	
	
	<!-- ================================= 
          target: create-binary-zipfile              
         ================================= -->
    <target name="create-binary-zipfile" depends="dist"
    	description="Create the binary distributable for windows">
    	
    	<zip destfile="${target.zip}"
    		duplicate="preserve">
    		<zipfileset file="${target.jar}"
    			prefix="${project.name-ver}" />
    		<zipfileset dir="${dist.dir}"
    			includes="*.bat,*.xml,*.properties"
    			prefix="${project.name-ver}" />
    		<zipfileset dir="${dist.lib.dir}"
    			includes="**/*"
    			prefix="${project.name-ver}/lib"/>
    		<zipfileset dir="${dist.doc.dir}"
    			includes="**/*"
    			prefix="${project.name-ver}/docs"/>
    		<zipfileset dir="${dist.javadoc.dir}"
    			includes="**/*"
    			prefix="${project.name-ver}/docs/javadoc"/>
    	</zip>
        
    </target>
	
	
	<!-- ================================= 
          target: unzip-dist              
         ================================= -->
    <target name="unzip-dist" depends="create-binary-zipfile" 
    	description="Unzips our distribution package to a set directory.">
    	
		<delete dir="${unzip.dir}" />
    	<unzip src="${target.zip}"
    	       dest="${unzip.dir}"/>
        
    </target>
 
 
</project>
                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384:
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
402:
403:
404:
405:

Select allOpen in new window

 

by: objectsPosted on 2008-12-07 at 19:04:55ID: 23118534

> foo/bar/SomeClass.properties

thats a path name, not a resource name.

> So when it looks for /foo/bar/SomeClass.properties it is finding classes/foo/bar/SomeClass.properties.

Resources are search for using the classpath, *not* the file system.

 

by: objectsPosted on 2008-12-07 at 19:09:25ID: 23118549

btw, if your interested the existing ResourceBundle class already handles loading properties file

 

by: cbuchPosted on 2008-12-07 at 19:14:02ID: 23118570

If the properties file is inside the jar when it is run, isn't that in the classpath?  How come it can find it when I run the jar from the command line, but not when I run it with Ant?  I am confused.

If I have the root directory of foo/bar/classes in the classpath, does it recursively add everything beneath it like foo/bar/classes/pkg1/pkg2/SomeClass.properties?

Thanks again.

--Charly

 

by: objectsPosted on 2008-12-07 at 19:24:30ID: 23118615

yes it will find it in the jar.
you just need to make sure the properties file is available somewhere in the classpath (in your case the one used by the system class loader).
It will use the package structure from the resource name when doing the search
ie. it looks for resources the same way it looks for class files.

You problem may be related to the fact that you're using the system classloader to search for the resource, not sure what classpath thats uses with ant.

 

by: cbuchPosted on 2008-12-07 at 19:48:25ID: 23118666

Ok, it looks like Ant uses it's own classloader.  Do you think it would be less of a pain to change the code rather than try a workaround for Ant?  I am not too familiar with property files though.

Thanks for your opinion.

--Charly

 

by: objectsPosted on 2008-12-07 at 19:53:02ID: 23118678

I'd be looking at the code first, have a look at ResourceBundle and see if it fits your needs.

When loading properties related to a class it is also useful to use the classes loader, and a relative name eg.

in = foo.getClass().getResourceAsStream("foo.properties");

 

by: cbuchPosted on 2008-12-07 at 19:57:03ID: 23118689

Another thing I don't understand is that I am running all my tests against a newly created jar file.  So if it can find files inside the jar file why can't Ant's classloader find those files?

I really want to automate all of my tests so that everytime the project is built it gets it's tests run, but it is seeming more difficult than I thought...

--Charly

 

by: cbuchPosted on 2008-12-07 at 19:58:05ID: 23118691

Ok, I'll have a look at that and let you know what I find out.  Thanks.

--Charly

 

by: cbuchPosted on 2008-12-07 at 21:04:44ID: 23118872

Thanks for your continued help objects, I really appreciate it.

Ok, so I tried the code below and still no dice, so I think I'll try and explain what is happening in the hopes that it becomes clearer to us both.  Here is the poor, sad life of the JCustomOpc.properties file...

Before the build is run, I have ./resources/javafish/clients/opc/JCustomOpc.properties.

When the build is run:

Ant adds all the jars in ./lib to it's classpath

Ant copies properties file over to ./build/classes/javafish/client/opc/JCustomOpc.properties

Ant packages the jar file with everything from ./build/classes

Ant adds the new jar file to it's classpath

Ant adds all the files in ./build/test/classes in it's classpath.

Ant copies properties file over to ./build/test/classes/javafish/client/opc/JCustomOpc.properties

Ant then runs the Junit tests and is unable to find JCustomOpc.properties.

static
  {
//    // load class properties
//    props = PropertyLoader.loadProperties(JCustomOpc.class);
//	  
//    // load native library OPC Client
//    System.loadLibrary(props.getProperty("library.path"));
	  	  
	  try
	  {
		  ResourceBundle bundle = ResourceBundle.getBundle("JCustomOpc.properties");
		  String libPath = bundle.getString("library.path");
		  System.loadLibrary(libPath);
		  System.out.println("Loaded: " + libPath);
	  }
	  catch(MissingResourceException mre)
	  {
		  System.err.println("Unable to locate JCustomOpc.properties.  Cannot continue.");
		  System.exit(1);
	  }
  }

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:

Select allOpen in new window

 

by: objectsPosted on 2008-12-07 at 21:12:52ID: 23118890

> Ant copies properties file over to ./build/test/classes/javafish/client/opc/JCustomOpc.properties

that step appears unnecessary as the properties are already in the jar

regards loading try:

props.load(JCustomOpc.class.getResourceAsStream("JCustomOpc.properties"));

or

ResourceBundle bundle = ResourceBundle.getBundle("javafish.client.opc.JCustomOpc");

 

by: CEHJPosted on 2008-12-08 at 01:08:37ID: 23119282

It would help to post the listing of the jar (jar tf your.jar)

What is that PropertyLoader class? Does it already use ResourceBundle?

 

by: cbuchPosted on 2008-12-08 at 08:49:03ID: 23121807

objects:

I am posting the code for all the different attempts I have been making.  I still can't seem to get it to work.  It's frustrating since I used properties files elsewhere in some of my tests (which I got to work) and that way doesn't seem to work for this problem.

There seems to be many different ways to read in a properties file.  Which is the best practice way to do it?

CEHJ:

PropertyLoader is a class in the library I am using to read in a properties file which has the location of a dll it needs.  The first code snippet I posted shows how they originally did it.  It used the system classloader instead of the contextual one, so objects and I think we are running into problems with the information being in the wrong classloader.

I attached my jars tf

static
  {
	  //ORIGINAL CODE
//    // load class properties
//    props = PropertyLoader.loadProperties(JCustomOpc.class);
//	  
//    // load native library OPC Client
//    System.loadLibrary(props.getProperty("library.path"));
	  
	  
	  //ATTEMPT #1
//	  try
//	  {
//		  ResourceBundle bundle = ResourceBundle.getBundle("javafish.client.opc.JCustomOpc");
//		  String libPath = bundle.getString("library.path");
//		  System.loadLibrary(libPath);
//	  }
//	  catch(MissingResourceException mre)
//	  {
//		  System.err.println("Unable to locate JCustomOpc.properties.  Cannot continue.");
//		  System.exit(1);
//	  }
	  
	  
	  //ATTEMPT #2
//	  try
//		{
//			props.load(JCustomOpc.class.getResourceAsStream("JCustomOpc.properties"));
//			System.loadLibrary(props.getProperty("library.path"));
//		}
//		catch(IOException ioe)
//		{
//			System.err.println("Unable to locate JCustomOpc.properties.  Cannot continue.");
//			System.exit(1);
//		}
	  
	  
	    //ATTEMPT #3
	  	//This is how I loaded other properties in my tests
	    FileReader reader = null;
	    
		try
		{
			reader = new FileReader(System.getProperty("JCustomOpc.properties"));
			Properties props = new Properties();
			props.load(reader);
		}
		catch(FileNotFoundException fnfe)
		{
			System.err.println("Unable to locate JCustomOpc.properties file.  Cannot continue.");
			System.exit(1);
		}
		catch(IOException ioe)
		{
			System.err.println("Error opening JCustomOpc.properties file.");
			System.exit(1);
		}
		finally
		{
			if(reader != null)
			{
				try
				{
					reader.close();
				}
				catch(IOException ioe)
				{
					System.err.println("Error closing JCustomOpc.properties file.");
				}
			}
		}
		
  }//end static()

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:

Select allOpen in new window

 

by: cbuchPosted on 2008-12-08 at 09:47:11ID: 23122305

Oh, I forgot to mention that in my build file, in order to load the test.properties file (the setup which works), I had to add a <sysproperty/> tag in the junit task like the code below.

I read that is the same as passing in the argument to the JVM: -Dtest.properties=test.properties

Thank you again for both your help.

--Charly

<junit printsummary="false" 
			errorProperty="test.failed" 
			failureProperty="test.failed">
			<classpath>
				<path refid="test.classpath" />
			</classpath>			
			<sysproperty key="test.properties" value="${test.properties.file}"/>			
			<sysproperty key="JCustomOpc.properties" value="${opc.lib.dir}"/>
			<formatter type="brief" usefile="false" />
			<formatter type="xml" />
			<test name="${testcase}" todir="${test.data.dir}" if="testcase" />
			<batchtest todir="${test.data.dir}" unless="testcase">
				<fileset dir="${test.classes.dir}">
					<patternset>
						<include name="**/test/*Test.class" />
						<exclude name="**/test/*Printer*.class" unless="test.properties.file" />
					</patternset>
				</fileset>
			</batchtest>
		</junit>

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:

Select allOpen in new window

 

by: CEHJPosted on 2008-12-08 at 10:00:00ID: 23122433

Try the following

URL url = WhateverYourClassIs.class.getResource("/javafish/clients/opc/JCustomOpc.properties");

                                              
1:

Select allOpen in new window

 

by: cbuchPosted on 2008-12-08 at 10:53:14ID: 23122921

CEHJ:

Now I think that the problem might not just be the properties file. After trying your suggestion, I hard-coded in the property I am looking for, and I am still getting the same errors.

It looks like  the dll my library needs isn't getting on the classpath.  I tried to add the dll to my classpath but I got a whole bunch more errors.  What's the best way to do that?

Sorry I keep jumping around like this.  I am not very experienced with using external dlls and such.  Thanks for your patience.

--Charly

try
		{
			URL url = JCustomOpc.class.getResource("/javafish/clients/opc/JCustomOpc.properties");
			props.load(new FileInputStream(new File(url.getFile())));
//			String libPath = props.getProperty("library.path");
			String libPath = "./lib/JCustomOpc.dll";
			System.loadLibrary(libPath);
		}
		catch(FileNotFoundException fnfe)
		{
			System.err.println("Unable to find JCustomOpc.properties file.");
			System.exit(1);
		}
		catch(IOException ioe)
		{
			System.err.println("Error opening JCustomOpc.properties file.");
			System.exit(1);
		}
 
 
Buildfile message excerpt:
 
 ------------- Standard Error -----------------
    [junit] Unable to find JCustomOpc.properties file.
    [junit] ------------- ---------------- ---------------
    [junit] Testcase: testSavePalletCount(fusionautomation.amc.labeler.test.AMCLabelServerTest):	Caused an ERROR
    [junit] null
    [junit] java.lang.ExceptionInInitializerError
    [junit] 	at fusionautomation.amc.labeler.test.AMCLabelServerTest.setUp(AMCLabelServerTest.java:73)
    [junit] 	at org.eclipse.ant.internal.ui.antsupport.EclipseDefaultExecutor.executeTargets(EclipseDefaultExecutor.java:32)
    [junit] 	at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.run(InternalAntRunner.java:423)
    [junit] 	at org.eclipse.ant.internal.ui.antsupport.InternalAntRunner.main(InternalAntRunner.java:137)
    [junit] Caused by: org.eclipse.ant.internal.ui.antsupport.AntSecurityException
    [junit] 	at org.eclipse.ant.internal.ui.antsupport.AntSecurityManager.checkExit(AntSecurityManager.java:54)
    [junit] 	at java.lang.Runtime.exit(Unknown Source)
    [junit] 	at java.lang.System.exit(Unknown Source)
    [junit] 	at javafish.clients.opc.JCustomOpc.<clinit>(JCustomOpc.java:161)

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:

Select allOpen in new window

 

by: CEHJPosted on 2008-12-08 at 11:05:49ID: 23123058

>>It looks like  the dll my library needs isn't getting on the classpath.

It's not the classpath it should be on but java.library.path

 

by: CEHJPosted on 2008-12-08 at 11:10:05ID: 23123100

You can ascertain what that is by getting your app to print that property as soon as it loads

 

by: cbuchPosted on 2008-12-08 at 13:04:46ID: 23124198

Well, I think we are getting closer to the real problem.  After doing some digging, I managed to set the java.library.path environment variable in the jvm that junit forks during the build.

I finally got it to run correctly,albeit with the hard-coded path to the library.  Now all I need is to figure out what is going wrong trying to look it up in the properties file, which is back to the original problem! heh

So now that we know it can find the library correctly, what would be a good next step trying to figure out why we can't find the properties file inside the jar?

--Charly

How I set the environment variable java.library.path in the jvm fork:
 
<junit printsummary="false" 
			fork="true"
			errorProperty="test.failed" 
			failureProperty="test.failed">
			<env key="java.library.path" path="${java.library.path};${basedir}/lib"/>
			<classpath>
				<path refid="test.classpath" />
			</classpath>			

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:

Select allOpen in new window

 

by: CEHJPosted on 2008-12-08 at 13:07:56ID: 23124232

Did my code give you a valid URL?

 

by: cbuchPosted on 2008-12-08 at 13:27:01ID: 23124426

When I try the code below, it crashes the JVM.  Did I implement it wrong somehow?

try
		{
		  	System.out.println("Attempting to locate JCustomOpc.properties...");
			URL url = JCustomOpc.class.getResource("/javafish/clients/opc/JCustomOpc.properties");
			System.out.println("URL=" + url);
			props.load(new FileInputStream(new File(url.getFile())));
			String libPath = props.getProperty("library.path");
//			String libPath = "/lib/JCustomOpc";
			System.loadLibrary(libPath);
		}
		catch(FileNotFoundException fnfe)
		{
			System.err.println("Unable to find JCustomOpc.properties file.");
			System.exit(1);
		}
		catch(IOException ioe)
		{
			System.err.println("Error opening JCustomOpc.properties file.");
			System.exit(1);
		}

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:

Select allOpen in new window

 

by: objectsPosted on 2008-12-08 at 13:28:59ID: 23124453

>                   URL url = JCustomOpc.class.getResource("/javafish/clients/opc/JCustomOpc.properties");

resource names have ., not /'s.   see my earlier example

>                   props.load(new FileInputStream(new File(url.getFile())));

if its finds it in a jar, then its not a file so you shouldn't treat it as one.

 

by: objectsPosted on 2008-12-08 at 13:30:13ID: 23124465

try this:

System.out.println(JCustomOpc.class.getResource("JCustomOpc.properties"));

 

by: CEHJPosted on 2008-12-08 at 13:33:23ID: 23124504

You can actually change to the below and get rid of the loadLibrary while you're testing

InputStream in = url.openStream();
props.load(in);
 
// Close 'in' later

                                              
1:
2:
3:
4:

Select allOpen in new window

 

by: CEHJPosted on 2008-12-08 at 13:37:40ID: 23124550

... and later you can simply call

InputStream in = WhateverYourClassIs.class.getResourceAsStream("/javafish/clients/opc/JCustomOpc.properties");

                                              
1:

Select allOpen in new window

 

by: cbuchPosted on 2008-12-08 at 14:01:35ID: 23124786

Thank you so much you two!  I finally got everything to work correctly.  Thanks for sticking with me on it.

--Charly

PS I attached what I finally came up with for future reference of anyone reading this

try
	  {
		  //load class properties
		  ResourceBundle bundle = ResourceBundle.getBundle("javafish.clients.opc.JCustomOpc");
		  String libPath = bundle.getString("library.path");
		  System.loadLibrary(libPath);
	  }
	  catch(MissingResourceException mre)
	  {
		  System.err.println("Unable to locate javafish.clients.opc.JCustomOpc.properties file.  Cannot continue.");
		  System.exit(1);
	  }

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:

Select allOpen in new window

 

by: cbuchPosted on 2008-12-08 at 14:04:25ID: 31523654

Great job.  Thanks!

 

by: objectsPosted on 2008-12-08 at 14:04:53ID: 23124817

>               ResourceBundle bundle = ResourceBundle.getBundle("javafish.clients.opc.JCustomOpc");

I suggested that many posts ago :)

 

by: cbuchPosted on 2008-12-08 at 14:20:54ID: 23124966

I know,but I think it didn't work due to the java.library.path not containing a reference to my ./lib directory like CEHJ pointed out.

It must have been getting the string from the properties file, but was then unable to load the library.  I just wasn't sharp enough at the time to piece it all together and figure it out.

 I didn't ignore your post, honest.

--Charly

 

by: objectsPosted on 2008-12-08 at 14:36:39ID: 23125101

> I know,but I think it didn't work due to the java.library.path not containing a reference to my ./lib directory


by the sounds you actually shouldn't be using java.library.path at all

 

by: cbuchPosted on 2008-12-08 at 15:31:21ID: 23125492

You know what, you're right.  I removed the java.library.path modifications in the build file and it still works.  Wow, I feel like a tool now.  I don't know what I did wrong when I originally tried your solution, but it does work like you said.

Looking over things again, it looks like your original post forgot the s in clients.  I'm not blaming you or anything, I should have caught that, but I missed it for whatever reason last night.  :/  Oh well...

Well, if I ever -do- need to modify the java.library.path later on, I guess I'll know how to now. :)

 

by: CEHJPosted on 2008-12-08 at 15:36:32ID: 23125530

>>I removed the java.library.path modifications in the build file and it still works.

It still works because your dll is still *on* java.library.path ;-)   java.library.path can't be ignored

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...