Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/385.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/16.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 从jar文件写入$HOME_Java_Scala_Bitcoin - Fatal编程技术网

Java 从jar文件写入$HOME

Java 从jar文件写入$HOME,java,scala,bitcoin,Java,Scala,Bitcoin,我正在尝试写入$HOME目录中的文件。写入该文件的代码已打包到jar文件中。当我运行单元测试来打包jar文件时,一切都按照预期工作——即填充文件并可以再次读取 当我尝试从另一个应用程序运行此代码时,jar文件包含在lib目录中,它失败了。文件已创建,但从未写入。当应用程序读取文件时,由于文件为空,因此无法解析该文件 以下是写入文件的代码: logger.warn("TestNet wallet does not exist creating one now in the directory:

我正在尝试写入$HOME目录中的文件。写入该文件的代码已打包到jar文件中。当我运行单元测试来打包jar文件时,一切都按照预期工作——即填充文件并可以再次读取

当我尝试从另一个应用程序运行此代码时,jar文件包含在
lib
目录中,它失败了。文件已创建,但从未写入。当应用程序读取文件时,由于文件为空,因此无法解析该文件

以下是写入文件的代码:

  logger.warn("TestNet wallet does not exist creating one now in the directory: " + walletPath)
  testNetFileName.createNewFile()
  logger.warn("Wallet file name: " + testNetFileName.getAbsolutePath)
  logger.warn("Can write: "+ testNetFileName.canWrite())
  logger.warn("Can read: " + testNetFileName.canRead)
  val w = Wallet.fromWatchingKey(TestNet3Params.get(), testNetSeed)
  w.autosaveToFile(testNetFileName, savingInterval, TimeUnit.MILLISECONDS, null)
  w
}
以下是与上述方法相关的日志格式:

2015-12-30 15:11:46,416 - [WARN] - from class com.suredbits.core.wallet.ColdStorageWallet$ in play-akka.actor.default-dispatcher-9 
TestNet wallet exists, reading in the one from disk

2015-12-30 15:11:46,416 - [WARN] - from class com.suredbits.core.wallet.ColdStorageWallet$ in play-akka.actor.default-dispatcher-9 
Wallet file name: /home/chris/testnet-cold-storage.wallet
然后它爆炸了

以下是
autoSaveToFile

public WalletFiles autosaveToFile(File f, long delayTime, TimeUnit timeUnit,
                                  @Nullable WalletFiles.Listener eventListener) {
    lock.lock();
    try {
        checkState(vFileManager == null, "Already auto saving this wallet.");
        WalletFiles manager = new WalletFiles(this, f, delayTime, timeUnit);
        if (eventListener != null)
            manager.setListener(eventListener);
        vFileManager = manager;
        return manager;
    } finally {
        lock.unlock();
    }
}
以及
钱包文件的定义

公共钱包文件(最终钱包、文件文件、长延迟、时间单位延迟时间单位){
//在需要时启动线程并在以后关闭它们的执行器。
this.executor=new ScheduledThreadPoolExecutor(1,new contextpropagationthreadfactory(“Wallet autosave thread”,thread.MIN_PRIORITY));
this.executor.setKeepAliveTime(5,TimeUnit.SECONDS);
this.executor.allowCoreThreadTimeOut(true);
this.executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
this.wallet=checkNotNull(wallet);
//从现在起,只能从自动保存执行器访问文件,以避免同时访问。
this.file=checkNotNull(文件);
this.savePending=new AtomicBoolean();
延迟=延迟;
this.delayTimeUnit=checkNotNull(delayTimeUnit);
this.saver=newcallable(){
@Override public Void call()引发异常{
//在自动保存线程中运行。
如果(!savePending.getAndSet(false)){
//其他一些预定的请求已经超过了我们。
返回null;
}
log.info(“后台保存钱包,最后看到的块是{}/{}”,wallet.getLastBlockSeenHeight(),wallet.getlastblockseenhah());
saveNowInternal();
返回null;
}
};
}
我猜这是某种权限问题,但我似乎无法理解


编辑:这一切都是在完全相同的Ubuntu 14.04机器上运行的-没有增加不同操作系统的复杂性

通常不能依赖
$HOME
的存在或可写性。实际上,只有两种可移植的方法可以识别(即提供指向)外部文件

  • 使用调用命令行上的属性集或环境中提供的属性提供显式路径,或
  • 在配置属性文件中提供路径,其位置本身在命令行或环境中作为属性提供
  • 使用
    $HOME
    的问题在于,您无法知道应用程序运行时使用的用户ID。用户可能有主目录,也可能没有主目录,即使用户有主目录,该目录也可能不可写。在您的特定情况下,您的进程可能能够创建文件(对目录本身的写访问),但对文件的写访问可能受到umask和/或acl(在Windows上)或selinux(在Linux上)的限制

    换句话说,库的安装程序/用户必须显式提供一个已知的可写路径供应用程序使用

    另一种思考方式是,您正在编写可能在完全未知的环境中使用的库代码。除了您和用户之间的明确合同中的内容外,您不能对外部环境进行任何假设。您可以在接口规范中声明,
    $HOME
    必须是可写的,但对于某些环境中没有
    $HOME
    可写的用户来说,这可能会非常不方便

    一个更好的、可移植的解决方案是

    在命令行上指定
    -Dcom.xyz.workdir=[path]
    ,以指示要使用的工作路径

    xyz库将在
    xyz_work
    环境变量指定的路径中查找其工作目录


    理想情况下,您可以同时执行这两项操作,以给用户一些灵活性。

    通常不能依赖
    $HOME
    的存在或可写性。实际上,只有两种可移植的方法可以识别(即提供指向)外部文件

  • 使用调用命令行上的属性集或环境中提供的属性提供显式路径,或
  • 在配置属性文件中提供路径,其位置本身在命令行或环境中作为属性提供
  • 使用
    $HOME
    的问题在于,您无法知道应用程序运行时使用的用户ID。用户可能有主目录,也可能没有主目录,即使用户有主目录,该目录也可能不可写。在您的特定情况下,您的进程可能能够创建文件(对目录本身的写访问),但对文件的写访问可能受到umask和/或acl(在Windows上)或selinux(在Linux上)的限制

    换句话说,库的安装程序/用户必须显式提供一个已知的可写路径供应用程序使用

    另一种思考方式是,您正在编写可能在完全未知的环境中使用的库代码。除了您和用户之间的明确合同中的内容外,您不能对外部环境进行任何假设。您可以在接口规范中声明,
    $HOME
    必须是可写的,但对于某些环境中没有
    $HOME
    可写的用户来说,这可能会非常不方便

    一个更好的、可移植的解决方案是

    在命令行上指定
    -Dcom.xyz.workdir=[path]
    ,以指示要使用的工作路径

    xyz库将查找其w
    public WalletFiles(final Wallet wallet, File file, long delay, TimeUnit delayTimeUnit) {
        // An executor that starts up threads when needed and shuts them down later.
        this.executor = new ScheduledThreadPoolExecutor(1, new ContextPropagatingThreadFactory("Wallet autosave thread", Thread.MIN_PRIORITY));
        this.executor.setKeepAliveTime(5, TimeUnit.SECONDS);
        this.executor.allowCoreThreadTimeOut(true);
        this.executor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
        this.wallet = checkNotNull(wallet);
        // File must only be accessed from the auto-save executor from now on, to avoid simultaneous access.
        this.file = checkNotNull(file);
        this.savePending = new AtomicBoolean();
        this.delay = delay;
        this.delayTimeUnit = checkNotNull(delayTimeUnit);
    
        this.saver = new Callable<Void>() {
            @Override public Void call() throws Exception {
                // Runs in an auto save thread.
                if (!savePending.getAndSet(false)) {
                    // Some other scheduled request already beat us to it.
                    return null;
                }
                log.info("Background saving wallet, last seen block is {}/{}", wallet.getLastBlockSeenHeight(), wallet.getLastBlockSeenHash());
                saveNowInternal();
                return null;
            }
        };
    }