JMockit jar loading from remote file systems enabled

Over the past few months we’ve faced significant hurdles integrating jmockit into our development environment at a client-site primarily but not entirely because it is not a conventional development environment. The most noteable of these has been the inability to load the jmockit jar file from a mounted drive which is a remote file system. Having remote paths in the classpath such as //foo/bar/baz/jmockit.jar would result in a being constructed with that remote path and the URI being passed to the following constructor.

public File(URI uri) {
    if (!uri.isAbsolute())
        throw new IllegalArgumentException("URI is not absolute");
    if (uri.isOpaque())
        throw new IllegalArgumentException("URI is not hierarchical");
    String scheme = uri.getScheme();
    if ((scheme == null) || !scheme.equalsIgnoreCase("file"))
        throw new IllegalArgumentException("URI scheme is not "file"");
    if (uri.getAuthority() != null)
        throw new IllegalArgumentException("URI has an authority component");
    if (uri.getFragment() != null)
        throw new IllegalArgumentException("URI has a fragment component");
    if (uri.getQuery() != null)
        throw new IllegalArgumentException("URI has a query component");
    String p = uri.getPath();
    if (p.equals(""))
        throw new IllegalArgumentException("URI path component is empty");
    p = fs.fromURIPath(p);
    if (File.separatorChar != '/')
        p = p.replace('/', File.separatorChar);
    this.path = fs.normalize(p);
    this.prefixLength = fs.prefixLength(this.path);

The following snippet in the above code would then result in an IllegalArgumentException being thrown with the message URI has an authority component and of course the authority component would be //foo.

if (uri.getAuthority() != null)
    throw new IllegalArgumentException("URI has an authority component");

This morning, however, I happened to notice the following extract in the jmockit changelog for the latest preview version – 0.997 although I’m not sure how long ago this was done.

A few fixes and enhancements to JMockit’s internal auto-initialization mechanisms: jmockit.jar (or a versioned jar name) can now be loaded from a remote file system without triggering a security-related exception

I wonder if this was in response to Shankar’s post on the obstacles we faced. It remains to be seen whether this indeed refers to the above issue and whether it resolves it. I’ll try it out once this version is finally released. Just for the record, to place renewed emphasis on the points made in Shankar’s article, the changes outlined in the following changelog entry under version 0.993 have caused us integration difficulties also.

Enhancement: to make JMockit easier to use when running under JDK 1.6+ without the -javaagent JVM parameter, two simplifications were introduced:

  • The /lib/tools.jar file no longer needs to be added to classpath.
  • Test classes no longer need to be annotated with @RunWith(JMockit.class) (for JUnit 4 tests), nor extend a JUnit/TestNG integration base class (JMockitTest, JMockitTestCase, JMockitTestNG).

There is a requirement for the second item when using JUnit, though: jmockit.jar needs to come before junit-4.x.jar in the classpath.

The above changes placed a constraint on classpath ordering and, by default, loaded all tests using the jmockit junit runner rather than the original junit runner and if jmockit wasn’t properly initialised then all tests would fail as long as jmockit was on the classpath. It’s a tricky problem to approach for jmockit. Making life easier for certain environments makes it more difficult in others. I would say that jmockit should allow the user to define how they would like their agent loaded and also have jmockit enabled explicitly only and not behind the scenes. Once integrated, however, it is a fine mocking library with a unique feature set.

Leave a Reply