Skip to content

JDOM2 Android Issue getSystemResource

rolfl edited this page Apr 23, 2012 · 4 revisions

JDOM JUnit tests use ClassLoader.getSystemResource("name") to create URLs that can be used as input to the various Build processes. When transferred to Android these tests have all been failing because the value returned from ClassLoader.getSystemResource(...) has been null.

The 'internet' is full of references to people complaining about this issue, but it is relatively sparse on clear references to a solution.

While I have 'wasted' a lot of time on this problem, the actual problem is one of my understanding (PICNIC - problem in chair, not in computer). As a result of 'study', I can make the following observations... (first though, some assumptions: you have a resource 'Data.txt' in your jar file, in the 'package' "net.tuis.cltest"):

  1. ClassLoader.getSystemResource("org/example/) will never likely give you what you want on Android.... the resources in your Jar files are not loaded by the Android equivalent of the 'System' class loader.
  2. this.getClass().getResource(...) will work on Android with limitations/expectations.
  3. this.getClass().getClassLoader().getResource(...) will also work on Android with limitations/expectations.

I have put together some test code.... the following methods:

	public final String getResource(final String res) {
		final StringBuilder sb = new StringBuilder();
		
		try {
			final String fmt = ("%s(%s%s)\n  %s\n");
			sb.append(String.format(fmt, "getSystemResource", "", res, ClassLoader.getSystemResource(res)));
			sb.append(String.format(fmt, "getSystemResource", "/", res, ClassLoader.getSystemResource("/" + res)));

			sb.append(String.format(fmt, "ClassLoader.getResource", "", res, this.getClass().getClassLoader().getResource(res)));
			sb.append(String.format(fmt, "ClassLoader.getResource", "/", res, this.getClass().getClassLoader().getResource("/" + res)));


			sb.append(String.format(fmt, "Class.getResource", "", res, this.getClass().getResource(res)));
			sb.append(String.format(fmt, "Class.getResource", "/", res, this.getClass().getResource("/" + res)));

		} catch (Throwable t) {
			StringWriter sw = new StringWriter();
			PrintWriter pw = new PrintWriter(sw);
			sb.append("\n\nGot Exception!!!!\n");
			t.printStackTrace(pw);
			pw.flush();
			sb.append(sw.toString());
		}
		
		return sb.toString();
	}

        public void onClick(View v) {
        	final GetResource gr = new GetResource();
        	StringBuilder sb = new StringBuilder();
        	sb.append(gr.getResource("Data.txt"));
        	sb.append(gr.getResource("net/tuis/cltest/Data.txt"));
        	Log.i("RGLRES", sb.toString());
            mEditor.setText(sb.toString());
        }

produce the following results:

04-22 23:56:42.990: I/RGLRES(740): getSystemResource(Data.txt)
04-22 23:56:42.990: I/RGLRES(740):   null
04-22 23:56:42.990: I/RGLRES(740): getSystemResource(/Data.txt)
04-22 23:56:42.990: I/RGLRES(740):   null
04-22 23:56:42.990: I/RGLRES(740): ClassLoader.getResource(Data.txt)
04-22 23:56:42.990: I/RGLRES(740):   null
04-22 23:56:42.990: I/RGLRES(740): ClassLoader.getResource(/Data.txt)
04-22 23:56:42.990: I/RGLRES(740):   null
04-22 23:56:42.990: I/RGLRES(740): Class.getResource(Data.txt)
04-22 23:56:42.990: I/RGLRES(740):   jar:file:/data/app/com.example.android.skeletonapp-1.apk!/net/tuis/cltest/Data.txt
04-22 23:56:42.990: I/RGLRES(740): Class.getResource(/Data.txt)
04-22 23:56:42.990: I/RGLRES(740):   null


04-22 23:56:42.990: I/RGLRES(740): getSystemResource(net/tuis/cltest/Data.txt)
04-22 23:56:42.990: I/RGLRES(740):   null
04-22 23:56:42.990: I/RGLRES(740): getSystemResource(/net/tuis/cltest/Data.txt)
04-22 23:56:42.990: I/RGLRES(740):   null
04-22 23:56:42.990: I/RGLRES(740): ClassLoader.getResource(net/tuis/cltest/Data.txt)
04-22 23:56:42.990: I/RGLRES(740):   jar:file:/data/app/com.example.android.skeletonapp-1.apk!/net/tuis/cltest/Data.txt
04-22 23:56:42.990: I/RGLRES(740): ClassLoader.getResource(/net/tuis/cltest/Data.txt)
04-22 23:56:42.990: I/RGLRES(740):   null
04-22 23:56:42.990: I/RGLRES(740): Class.getResource(net/tuis/cltest/Data.txt)
04-22 23:56:42.990: I/RGLRES(740):   null
04-22 23:56:42.990: I/RGLRES(740): Class.getResource(/net/tuis/cltest/Data.txt)
04-22 23:56:42.990: I/RGLRES(740):   jar:file:/data/app/com.example.android.skeletonapp-1.apk!/net/tuis/cltest/Data.txt

Running the same code on vanilla Java6

getSystemResource(Data.txt)
  null
getSystemResource(/Data.txt)
  null
ClassLoader.getResource(Data.txt)
  null
ClassLoader.getResource(/Data.txt)
  null
Class.getResource(Data.txt)
  file:/C:/workspace/ClassLoaderResource/ebuild/net/tuis/cltest/Data.txt
Class.getResource(/Data.txt)
  null


getSystemResource(net/tuis/cltest/Data.txt)
  file:/C:/workspace/ClassLoaderResource/ebuild/net/tuis/cltest/Data.txt
getSystemResource(/net/tuis/cltest/Data.txt)
  null
ClassLoader.getResource(net/tuis/cltest/Data.txt)
  file:/C:/workspace/ClassLoaderResource/ebuild/net/tuis/cltest/Data.txt
ClassLoader.getResource(/net/tuis/cltest/Data.txt)
  null
Class.getResource(net/tuis/cltest/Data.txt)
  null
Class.getResource(/net/tuis/cltest/Data.txt)
  file:/C:/workspace/ClassLoaderResource/ebuild/net/tuis/cltest/Data.txt
Clone this wiki locally