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

paf*_* k. 11 java jpa classloader

我正在尝试扩展我的库以进行集成Swing,JPA并将JPA配置设置为可自动(和可移植),这意味着以编程方式添加<class>元素.(我知道它可以通过Hibernate AnnotationConfiguration或EclipseLInk 完成ServerSession,但是 - 可移植性).我也想避免Spring仅仅为了这个目的而使用.

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

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

编辑(尝试更清楚):

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

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

我的想法是建立一个习俗ClassLoader- 如果你有任何其他的我会感激,我不会在这个上面.

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

这就是我正在设置的方式,但它是通过写入persistenceXmlFile = new File("META-INF/persistence.xml")磁盘来实现的:

Thread.currentThread().setContextClassLoader(
    new URLResourceClassLoader(
        new URL[] { persistenceXmlFile.toURI().toURL() },
        Thread.currentThread().getContextClassLoader()
    )
);
Run Code Online (Sandbox Code Playgroud)

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

NSV*_*NSV 8

也许有点晚了(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<URL, byte[]> 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());
                }

            };
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

  • 它是apache commons io的一部分:https://commons.apache.org/proper/commons-io/apidocs/org/apache/commons/io/IOUtils.html#toByteArray-java.io.InputStream- (2认同)