2

I'm having some trouble with my spring-shell.log. Not a big problem but really annoying. Once I run my application from outside of my workspace, spring shell tries to save the spring-shell.log in a directory which is protected by windows. This results in not having a shelö history. Now I simply like to save the file somewhere else

My favorite way would be to change the location via application.properties. But I don't know if there is a properties for this. I'd be fine with changing the logback-spring.xml as well.

java.nio.file.AccessDeniedException: C:\Windows\spring-shell.log
        at sun.nio.fs.WindowsException.translateToIOException(Unknown Source) ~[na:1.8.0_191]
        at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source) ~[na:1.8.0_191]
        at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source) ~[na:1.8.0_191]
        at sun.nio.fs.WindowsFileSystemProvider.newByteChannel(Unknown Source) ~[na:1.8.0_191]
        at java.nio.file.spi.FileSystemProvider.newOutputStream(Unknown Source) ~[na:1.8.0_191]
        at java.nio.file.Files.newOutputStream(Unknown Source) ~[na:1.8.0_191]
        at java.nio.file.Files.newBufferedWriter(Unknown Source) ~[na:1.8.0_191]
        at java.nio.file.Files.newBufferedWriter(Unknown Source) ~[na:1.8.0_191]
        at org.jline.reader.impl.history.DefaultHistory.save(DefaultHistory.java:121) ~[jline-3.4.0.jar!/:na]
        at org.jline.reader.impl.history.DefaultHistory.add(DefaultHistory.java:248) ~[jline-3.4.0.jar!/:na]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_191]
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_191]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_191]
        at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_191]
        at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343) [spring-aop-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:205) [spring-aop-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
        at com.sun.proxy.$Proxy52.add(Unknown Source) [na:na]
        at org.jline.reader.impl.LineReaderImpl.finishBuffer(LineReaderImpl.java:864) [jline-3.4.0.jar!/:na]
        at org.jline.reader.impl.LineReaderImpl.readLine(LineReaderImpl.java:557) [jline-3.4.0.jar!/:na]
        at org.jline.reader.impl.LineReaderImpl.readLine(LineReaderImpl.java:390) [jline-3.4.0.jar!/:na]
        at org.springframework.shell.jline.InteractiveShellApplicationRunner$JLineInputProvider.readInput(InteractiveShellApplicationRunner.java:115) [spring-shell-core-2.0.1.RELEASE.jar!/:2.0.1.RELEASE]
        at org.springframework.shell.Shell.run(Shell.java:129) [spring-shell-core-2.0.1.RELEASE.jar!/:2.0.1.RELEASE]
        at org.springframework.shell.jline.InteractiveShellApplicationRunner.run(InteractiveShellApplicationRunner.java:84) [spring-shell-core-2.0.1.RELEASE.jar!/:2.0.1.RELEASE]
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:770) [spring-boot-2.1.6.RELEASE.jar!/:2.1.6.RELEASE]
        at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:760) [spring-boot-2.1.6.RELEASE.jar!/:2.1.6.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:318) [spring-boot-2.1.6.RELEASE.jar!/:2.1.6.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1213) [spring-boot-2.1.6.RELEASE.jar!/:2.1.6.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1202) [spring-boot-2.1.6.RELEASE.jar!/:2.1.6.RELEASE]
        at com.provinzial.convenience.tools.Application.main(Application.java:12) [classes!/:0.0.1-SNAPSHOT]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_191]
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_191]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_191]
        at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_191]
        at org.springframework.boot.loader.MainMethodRunner.run(MainMethodRunner.java:47) [convenience-tools-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:86) [convenience-tools-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
        at org.springframework.boot.loader.Launcher.launch(Launcher.java:50) [convenience-tools-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
        at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:51) [convenience-tools-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]

I'm grateful for any hint. Thanks guys. Best regards, Sebastian

1 Answers1

3

In your Spring project, just create a new class like this:

package com.example.shell.demo.config;

import org.jline.reader.History;
import org.jline.reader.LineReader;
import org.jline.reader.impl.history.DefaultHistory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.EventListener;

import java.io.IOException;
import java.nio.file.Paths;

@Configuration
public class HistoryConfiguration {

    @Autowired
    private History history;

    @Bean
    public History history(LineReader lineReader, @Value("${app.history.file}") String historyPath) {
        lineReader.setVariable(LineReader.HISTORY_FILE, Paths.get(historyPath));
        return new DefaultHistory(lineReader);
    }

    @EventListener
    public void onContextClosedEvent(ContextClosedEvent event) throws IOException {
        history.save();
    }
}

Then, in your application.properties file, create a key / value pair like this

app.history.file=<path to your log file>

The original solution was posted here: https://github.com/spring-projects/spring-shell/issues/220. I have tested it with Spring Shell 2.0.0-RELEASE and it works well.

Hope that helps.

André Gasser
  • 1,065
  • 2
  • 14
  • 34