是否可以创建指向内存中对象的URL?

我正在尝试通过将JPA配置设置为自动(和可移植)来扩展我的库以集成SwingJPA ,这意味着以编程方式添加元素。 (我知道它可以通过Hibernate的AnnotationConfiguration或EclipseLInk的ServerSession ,但是 – 可移植性)。 我也想避免将Spring用于此目的。

我可以动态创建一个persistence.xml ,并用指定包中的元素填充它(通过Reflections库)。 当我尝试将此persistence.xml提供给JPA提供程序时,问题就开始了。 我能想到的唯一方法是设置一个URLClassLoader ,但我想不出一种方法,首先不能让我把文件写到磁盘上,因为它只能获得有效的URL 。 通过URLlocalhost:xxxx )设置套接字来提供文件似乎……我不知道,邪恶?

有谁知道如何解决这个问题? 我知道避免使用一个库听起来很多工作,但我只想知道它是否可以完成。

编辑 (尝试更清楚):

动态生成的XML保存在String对象中。 我不知道如何将它提供给持久性提供程序 另外,我想避免将文件写入磁盘。

出于我的问题的目的, 持久性提供程序只是一个类,它扫描META-INF/persistence.xml的类路径。 可以使一些实现接受动态创建XML ,但是没有通用接口(特别是对于文件的关键部分, 标记)。

我的想法是建立一个自定义的ClassLoader – 如果你有任何其他的我会感激,我不会在这个上面。

我能找到的唯一易于扩展/可配置的是URLClassLoader 。 它适用于URL对象,我不知道是否可以创建一个而不首先实际将XML写入磁盘。

这就是我正在设置的方法,但它的工作原理是将persistenceXmlFile = new File("META-INF/persistence.xml")写入磁盘:

 Thread.currentThread().setContextClassLoader( new URLResourceClassLoader( new URL[] { persistenceXmlFile.toURI().toURL() }, Thread.currentThread().getContextClassLoader() ) ); 

URLResourceClassLoaderURLCLassLoader的子类,它允许通过重写public Enumeration findResources(String name)来查找资源和类。

也许有点晚了(4年后),但对于寻找类似解决方案的其他人来说,您可以使用我创建的URL工厂:

 public class InMemoryURLFactory { public static void main(String... args) throws Exception { URL url = InMemoryURLFactory.getInstance().build("/this/is/a/test.txt", "This is a test!"); byte[] data = IOUtils.toByteArray(url.openConnection().getInputStream()); // Prints out: This is a test! System.out.println(new String(data)); } private final Map contents = new WeakHashMap<>(); private final URLStreamHandler handler = new InMemoryStreamHandler(); private static InMemoryURLFactory instance = null; public static synchronized InMemoryURLFactory getInstance() { if(instance == null) instance = new InMemoryURLFactory(); return instance; } private InMemoryURLFactory() { } public URL build(String path, String data) { try { return build(path, data.getBytes("UTF-8")); } catch (UnsupportedEncodingException ex) { throw new RuntimeException(ex); } } public URL build(String path, byte[] data) { try { URL url = new URL("memory", "", -1, path, handler); contents.put(url, data); return url; } catch (MalformedURLException ex) { throw new RuntimeException(ex); } } private class InMemoryStreamHandler extends URLStreamHandler { @Override protected URLConnection openConnection(URL u) throws IOException { if(!u.getProtocol().equals("memory")) { throw new IOException("Cannot handle protocol: " + u.getProtocol()); } return new URLConnection(u) { private byte[] data = null; @Override public void connect() throws IOException { initDataIfNeeded(); checkDataAvailability(); // Protected field from superclass connected = true; } @Override public long getContentLengthLong() { initDataIfNeeded(); if(data == null) return 0; return data.length; } @Override public InputStream getInputStream() throws IOException { initDataIfNeeded(); checkDataAvailability(); return new ByteArrayInputStream(data); } private void initDataIfNeeded() { if(data == null) data = contents.get(u); } private void checkDataAvailability() throws IOException { if(data == null) throw new IOException("In-memory data cannot be found for: " + u.getPath()); } }; } } }