Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是否可以创建指向内存中对象的URL?_Java_Jpa_Classloader - Fatal编程技术网

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

Java 是否可以创建指向内存中对象的URL?,java,jpa,classloader,Java,Jpa,Classloader,我试图通过将JPAconfig设置为自动(可移植),扩展我的库,以集成Swing和JPA,这意味着以编程方式添加元素。(我知道这可以通过Hibernate的注释配置或EclipseLInk的服务器会话来实现,但是-可移植性)。我还希望避免仅为了这个目的而使用Spring 我可以动态创建persistence.xml,并使用指定包中的元素(通过反射库)填充它。当我尝试将这个persistence.xml提供给JPA提供者时,问题就开始了。我能想到的唯一方法是设置一个URLClassLoader,但

我试图通过将
JPA
config设置为自动(可移植),扩展我的库,以集成
Swing
JPA
,这意味着以编程方式添加
元素。(我知道这可以通过Hibernate的
注释配置
或EclipseLInk的
服务器会话
来实现,但是-可移植性)。我还希望避免仅为了这个目的而使用
Spring

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

有人知道我如何解决这个问题吗?我知道避免使用一个库听起来需要做很多工作,但我只是想知道是否可以做到

编辑(尝试更清晰):

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

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

我的想法是建立一个定制的
类加载器
——如果您还有其他的,我将不胜感激,我不打算这样做

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

我就是这样设置的,但它是通过将
persistenceXmlFile=new文件(“META-INF/persistence.xml”)
写入磁盘来工作的:

Thread.currentThread().setContextClassLoader(
    new URLResourceClassLoader(
        new URL[] { persistenceXmlFile.toURI().toURL() },
        Thread.currentThread().getContextClassLoader()
    )
);
URLResourceClassLoader
URLCLassLoader
的子类,它允许通过覆盖
公共枚举findResources(字符串名称)
查找资源和类,可能有点晚(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());
                }

            };
        }

    }
}
内存工厂中的公共类{
公共静态void main(字符串…参数)引发异常{
URL URL=InMemoryURLFactory.getInstance().build(“/this/is/a/test.txt”,“这是一个测试!”);
byte[]data=IOUtils.toByteArray(url.openConnection().getInputStream());
//打印出来:这是一个测试!
System.out.println(新字符串(数据));
}
私有最终地图内容=新WeakHashMap();
private final URLStreamHandler=新InMemoryStreamHandler();
私有静态InMemoryURLFactory实例=null;
公共静态同步InMemoryURLFactory getInstance(){
if(实例==null)
实例=新的InMemoryURLFactory();
返回实例;
}
私有InMemoryURLFactory(){
}
公共URL生成(字符串路径、字符串数据){
试一试{
返回构建(路径、数据.getBytes(“UTF-8”);
}捕获(不支持DencodingException ex){
抛出新的运行时异常(ex);
}
}
公共URL生成(字符串路径,字节[]数据){
试一试{
URL=新URL(“内存”、“”、-1、路径、处理程序);
contents.put(url、数据);
返回url;
}捕获(格式错误){
抛出新的运行时异常(ex);
}
}
MemoryStreamHandler中的私有类扩展了URLStreamHandler{
@凌驾
受保护的URL连接openConnection(URL u)引发IOException{
如果(!u.getProtocol().equals(“内存”)){
抛出新IOException(“无法处理协议:+u.getProtocol());
}
返回新的URL连接(u){
专用字节[]数据=null;
@凌驾
public void connect()引发IOException{
initDataIfNeeded();
checkDataAvailability();
//超类的受保护字段
连接=真;
}
@凌驾
公共长getContentLengthLong(){
initDataIfNeeded();
如果(数据==null)
返回0;
返回数据长度;
}
@凌驾
公共InputStream getInputStream()引发IOException{
initDataIfNeeded();
checkDataAvailability();
返回新的ByteArrayInputStream(数据);
}
私有void initDataIfNeeded(){
如果(数据==null)
数据=内容。获取(u);
}
私有void checkDataAvailability()引发IOException{
如果(数据==null)
抛出新IOException(“找不到内存中的数据:“+u.getPath()”);
}
};
}
}
}
我们可以使用谷歌图书馆来实现这一点

首先,我们需要将以下内容添加到我们的项目中:

<dependency>
  <groupId>com.google.jimfs</groupId>
  <artifactId>jimfs</artifactId>
  <version>1.2</version>
</dependency>

com.google.jimfs


如果我们看一下内部,我们会发现实现类似于@NSV answer。

你的意思是真的,还是“一个只存在于内存中的对象?”我还想知道是否可能,如备忘录所示
public static final String INPUT =
      "\n"
          + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
          + "<note>\n"
          + "  <to>Tove</to>\n"
          + "  <from>Jani</from>\n"
          + "  <heading>Reminder</heading>\n"
          + "  <body>Don't forget me this weekend!</body>\n"
          + "</note>";

@Test
void usingJIMFS() throws IOException {
  try (var fs = Jimfs.newFileSystem(Configuration.unix())) {
    var path = fs.getPath(UUID.randomUUID().toString());
    Files.writeString(path, INPUT);
    var url = path.toUri().toURL();

    assertThat(url.getProtocol()).isEqualTo("jimfs");
    assertThat(Resources.asCharSource(url, UTF_8).read()).isEqualTo(INPUT);
  }
}