Anyone who has used Web Start has come across the problem that it forces you to store everything in JAR files. This is especially annoying because there are multiple ways to load a file from the classpath (MyClass.class.getClassLoader.getResource(...) and Thread.currentThread().getContextClassLoader().getResource(...)). Also, when you're developing it's more convenient to only have to change a local file, instead of having to create the JARs again every time you make a change.
The class below allows you to develop using local files, and to load them from the classpath when deployed as Web Start application. This works without code changes, so you don't have to have DEVELOP_MODE = true flags in your code. I guess a lot of people who will read this already have a similar (and probably better) way to tackle this problem, but it might just help one guy who is trying to figure out Web Start.
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
| import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.net.URL;
public class ResourceFile { private String path; private File localFile; private URL classpath;
public ResourceFile(String path) { path = path.trim(); if (path.length() == 0) { throw new IllegalArgumentException("Path is empty. If you want to " + "indicate the current directory use \".\""); } path = path.replace('\\', '/'); if (path.endsWith("/")) { path = path.substring(0, path.length() - 1); } if ((path.length() > 2) && (path.startsWith("./"))) { path = path.substring(2); } this.path = path; localFile = new File(path); classpath = getClass().getClassLoader().getResource(path); } public ResourceFile(ResourceFile dir, String name) { this(dir.getPath() + "/" + name); } public ResourceFile(File file) { this(file.getAbsolutePath()); } public String getPath() { return path; } public String getName() { int slashIndex = path.lastIndexOf('/'); if (slashIndex == -1) { return path; } return path.substring(slashIndex + 1); } public boolean exists() { return (existsLocal() || existsClassPath()); } public boolean existsLocal() { return localFile.exists(); } public boolean existsClassPath() { return (classpath != null); } public InputStream getStream() { if (existsLocal()) { try { return new FileInputStream(localFile); } catch (FileNotFoundException e) { throw new ResourceNotFoundException(this); } } else if (existsClassPath()) { try { return classpath.openStream(); } catch (IOException e) { throw new ResourceNotFoundException(this); } } else { throw new ResourceNotFoundException(this); } } public URL getURL() { if (existsLocal()) { try { return localFile.toURI().toURL(); } catch (IOException e) { throw new AssertionError(e); } } else if (existsClassPath()) { return classpath; } else { throw new ResourceNotFoundException(this); } } public final byte[] getBytes() { try { return toByteArray(getStream()); } catch (IOException e) { throw new IllegalStateException("Could not convert file to bytes", e); } } private byte[] toByteArray(InputStream input) throws IOException { ByteArrayOutputStream output = new ByteArrayOutputStream(); toStream(input, output); input.close(); output.close(); return output.toByteArray(); } private void toStream(InputStream input, OutputStream output) throws IOException { byte[] buffer = new byte[2048]; int length = -1; while ((length = input.read(buffer, 0, buffer.length)) != -1) { output.write(buffer, 0, length); } } public File toLocalFile() { return localFile; } @Override public boolean equals(Object o) { if (o instanceof ResourceFile) { return path.equals(((ResourceFile) o).path); } return false; } @Override public int hashCode() { return path.hashCode(); } @Override public String toString() { return path; } } |