0

I am attempting to solve a problem by extending URLStreamHandler with the goal of providing a file from memory. I have the class...

public class CustomURLStreamHandler extends URLStreamHandler {
    private Handler fileHandler = new Handler();

    @Override
    protected URLConnection openConnection(URL url) throws IOException {
        if (url.toString().contains(".mp4")) {
            return new CustomURLConnection(url);
        }

        return fileHandler.openConnection(url);
    }
}

...which is going to try to change the way MP4s are loaded. For example, say I have a really large video file and in order to save memory, I want to only have X bytes of it loaded at any given time. The CustomURLConnection is here...

public class CustomURLConnection extends URLConnection {
    public CustomURLConnection(URL url) {
        super(url);
    }

    @Override
    public void connect() throws IOException {
        // Nothing needed
    }

    @Override
    public synchronized java.io.InputStream getInputStream() throws IOException {
        return new CustomInputStream(this.url)));
    }
}

...but note that the getInputStream is not doing what it looks like. After much investigation, it seems that the URL connection's getInputStream is ONLY used to determine the content type of the media. In my case, it only looks at the first 22 bytes. If I change the method to...

@Override
public synchronized java.io.InputStream getInputStream() throws IOException {
    try {
        return new ByteInputStream(new byte[] {}, 0);
    }
}

...the file will still load... because this input stream is only being used to detect the content type and if it fails, Java will try to determine the content type using an unknown content handler at first that uses the URL and figures everything out. An important note is that I use my CustomURLStreamHandler and CustomURLConnection by changing my main method to...

public static void main(String[] args) {
    URL.setURLStreamHandlerFactory(new CustomURLStreamHandlerFactory());
    launch(args);
}

...and in the CustomURLStreamHandlerFactory, I use my CustomURLStreamHandler when the protocol is "file". It seems to me that the last piece of the puzzle is extend the content handler for the MP4 MIME.

Herein lies my problem, I changed my main method to...

public static void main(String[] args) {
    URL.setURLStreamHandlerFactory(new CustomURLStreamHandlerFactory());
    URLConnection.setContentHandlerFactory(new CustomContentHandlerFactory());
    launch(args);
}

...and I put a breakpoint in the overridden method "createContentHandler" but it NEVER gets hit. I tried this using the java.net and the sun.net.www URLConnection (although I am 99% sure the java.net one is the correct one to use). I am quite sure that if I can hook into the content handler I care about, I can get this working. My java version...

java version "1.8.0_05"
Java(TM) SE Runtime Environment (build 1.8.0_05-b13)
Java HotSpot(TM) 64-Bit Server VM (build 25.5-b02, mixed mode)

Has anyone had success supplying custom content handlers? Any help is much appreciated, thanks.

Lane
  • 685
  • 2
  • 10
  • 25
  • Your question lacks information on how the `URL` is actually accessed. In the end it’s your(?) application that opens it and may have the freedom to access the file directly if it detects that the `URL` has a `file` protocol. As far as I can see, Java does not do such things when `openStream()` or `getContent()` is invoked on a `URL`. But these methods also do not try to guess the content type from the `InputStream`, so it would be helpful to know what operation you are actually performing on the `URL`… – Holger Apr 28 '14 at 18:46
  • I am not creating the URL directly and performing operations on it. I am creating a new Media object in JavaFX and passing it a file URL (as a string). It then calls getInputStream on the URL Connection and eventually calls getContent on the ContentHandler. This method returns an object and I was hoping to provide a custom object that can load on demand or whatever else I need. I am not sure if this is possible, it very well may not be and it seems that's how they designed it. – Lane Apr 28 '14 at 20:36
  • [tag:JavaFX] is the important key here as it seems to be a property of `JavaFX` to bypass the entire Java URL handling code. That’s why the `MediaPlayer` doesn’t work with arbitrary `URL` protocols but only with the protocols it knows how to handle itself. And it doesn’t seem to be a [tag:java-8] issue either. – Holger Apr 29 '14 at 09:00

0 Answers0