0

I'm using commons-vfs and for my tests I want to use a ram file system. When I try with new URL("ram:///A/B/sample.jar") I get the following exception:

java.net.MalformedURLException: unknown protocol: ram
    at java.net.URL.<init>(URL.java:592)
    at java.net.URL.<init>(URL.java:482)
    at java.net.URL.<init>(URL.java:431)

Here is some code (when I use file protocol everything works fine)

// URL is used to construct an object
obj.addArchive(new URL("ram:///A/B/sample.jar"))    
...
// then VFS is used to scan the object urls
// for instance get the parent directory
FileSystemManager manager = VFS.getManager();
String directory = manager.resolveFile(obj.getPath()).getParent().getURL().toExternalForm();

How I could use ram protocol in java.net.URL?

bachr
  • 5,780
  • 12
  • 57
  • 92
  • Where in the commons-VFS documentation does it say you need to use the URL class? – Gimby Dec 08 '14 at 10:30
  • I need `URL` to construct an object that will later be scanned and at this moment VFS is used. – bachr Dec 08 '14 at 10:31
  • That's great, but just because VFS understands a RAM filesystem doesn't mean that standard Java URL is ever going to understand it. Most likely your code is not using VFS properly at all and right now it works by accident. You'd need to post more code to say that for certain. – Gimby Dec 08 '14 at 12:30
  • I'm aware of that, I just look for any existing url handlers for ram to not have to write my own handler as in [link 1](http://mjremijan.blogspot.fr/2012/02/create-your-own-java-url-handlers.html) or [link 2](http://www.cooljeff.co.uk/2009/12/12/custom-url-protocols-and-multiple-classloaders/). I've edited the post with some code. – bachr Dec 08 '14 at 13:28

2 Answers2

0

I've found a solution based on the use of custom URL handlers as described here.

Add a maven dependency to url-scheme-registry:

<dependency>
    <groupId>org.skife.url</groupId>
    <artifactId>url-scheme-registry</artifactId>
    <version>0.0.1</version>
</dependency>

Create a custom URLStreamHandler for the ram schema:

public class RamHandler extends URLStreamHandler { 
  @Override
  protected URLConnection openConnection(final URL u) throws IOException {
    //May instead use VFS DefaultURLConnection
    return new URLConnection(u) {
      @Override
      public void connect() throws IOException {}

      @Override
      public InputStream getInputStream() throws IOException {
        FileSystemManager fsManager = VFS.getManager();
        FileObject entry = fsManager.resolveFile(u.toExternalForm());
        FileContent content = entry.getContent();
        return content.getInputStream();
      }
    };
  }
}

Then there will be no malformed url exception:

UrlSchemeRegistry.register("ram", RamHandler.class);
URL url = new URL("ram:///A/B/sample.jar");
bachr
  • 5,780
  • 12
  • 57
  • 92
0

VFS supports creating a stream handler factory which knows about all the registered schemes.

// you might want to configure a manager with less schemes
FileSystemManager fsm = VFS.getManager(); 
URLStreamHandlerFactory factory = fsm.getURLStreamHandlerFactory();
URL.setURLStreamHandlerFactory(factory); // VM global
URL url = new URL("ram://test.txt");
eckes
  • 10,103
  • 1
  • 59
  • 71