我正在 build.gradle 文件中将 SnakeYAML 版本从 1.3.2 更改为 2.0。使用 SnakeYAML 1.3.2 编写的 Java 代码存在编译问题

问题描述 投票:0回答:1

我正在 build.gradle 文件中将 SnakeYAML 版本从 1.3.2 更改为 2.0。使用SnakeYAML 1.3.2编写的java代码出现以下编译问题。

package uscrn.archive.environment;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Path;
import java.time.Instant;
import java.time.YearMonth;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.AbstractConstruct;
import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.constructor.SafeConstructor;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.ScalarNode;
import org.yaml.snakeyaml.nodes.Tag;
import org.yaml.snakeyaml.representer.Represent;
import org.yaml.snakeyaml.representer.Representer;
import uscrn.archive.io.FileReadFailed;
import uscrn.archive.io.FileWriteFailed;

/**
 * An implementation of WorkLog that persists information to the local file
 * system in the Yaml text format.  This allows the application to record
 * the work it does, and later query the record for decision making.
 */
public class YamlFileWorkLog implements WorkLog {
    private final File file;
    private final TreeMap<YearMonth, Instant> entries;

    public YamlFileWorkLog(File file) {
        this.file = file;
        this.entries = load(file);
    }

    public YamlFileWorkLog(Path path){
        this(path.toFile());
    }

    @SuppressWarnings("unchecked")
    private TreeMap<YearMonth, Instant> load(File file) {
        TreeMap<YearMonth, Instant> result = new TreeMap<>();
        try(InputStream input = new FileInputStream(file)){
            Map<YearMonth, Instant> loaded = (Map<YearMonth, Instant>) yaml().load(input);
            if(loaded != null){
                result.putAll(loaded);
            }
            return result;
        } catch (IOException e) {
            throw new FileReadFailed(file.toPath(), e);
        }
    }

    @Override
    public Instant lookup(YearMonth month) {
        return entries.get(month);
    }

    @Override
    public void record(YearMonth month, Instant timestamp) {
        entries.put(month, timestamp);
    }

    @Override
    public void clear() {
        entries.clear();
    }

    @Override
    public boolean hasRecorded(YearMonth month) {
        return entries.containsKey(month);
    }

    @Override
    public void save() {
        try(FileWriter output = new FileWriter(file)){
            yaml().dump(entries, output);
        } catch (IOException e) {
            throw new FileWriteFailed(file.toPath(), e);
        }
    }

    @Override
    public int size() {
        return entries.size();
    }

    @Override
    public Instant latestTimestamp(){
        Instant timestamp = null;
        for(Entry<YearMonth, Instant> entry : entries.entrySet()){
            if(timestamp == null || timestamp.isBefore(entry.getValue())){
                timestamp = entry.getValue();
            }
        }
        return timestamp;
    }

    @Override
    public String toString(){
        return yaml().dump(entries);
    }

    /**
     * Returns an Yaml object that is configured to read and write WorkLog
     * information.
     * @return A configured Yaml object.
     */
    private Yaml yaml(){
        DumperOptions options = new DumperOptions();
        options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
        return new Yaml(new LogConstructor(), new LogRepresenter(), options);
    }

    /**
     * A class that is used by the Yaml library to convert WorkLog entries
     * into Yaml constructs, which can then be written out as text.
     */
    private class LogRepresenter extends Representer {
        public LogRepresenter() {
            this.representers.put(YearMonth.class,
                new Represent(){
                    @Override
                    public Node representData(Object data) {
                        YearMonth month = (YearMonth) data;
                        return representScalar(new Tag("!month"), month.toString());
                    }
                }
            );
            this.representers.put(Instant.class,
                new Represent(){
                    @Override
                    public Node representData(Object data) {
                        Instant timestamp = (Instant) data;
                        return representScalar(Tag.TIMESTAMP, timestamp.toString());
                    }
                }
            );
        }
    }

    /**
     * A class that is used by the Yaml library to convert text into WorkLog
     * entries.
     */
    private class LogConstructor extends SafeConstructor {
        public LogConstructor() {
            this.yamlConstructors.put(new Tag("!month"),
                new AbstractConstruct(){
                    @Override
                    public Object construct(Node node) {
                        String val = (String) constructScalar((ScalarNode) node);
                        Integer year = Integer.parseInt(val.substring(0, 4));
                        Integer month = Integer.parseInt(val.substring(5, 7));
                        return YearMonth.of(year, month);
                    }
                }
            );
            this.yamlConstructors.put(Tag.TIMESTAMP,
                new AbstractConstruct(){
                    @Override
                    public Object construct(Node node) {
                        String val = (String) constructScalar((ScalarNode) node);
                        return Instant.parse(val);
                    }
                }
            );
        }
    }
}

编译错误1:Representer类中的构造函数Representer不能应用于给定类型;必需:DumperOptionsfound:noargumentsreason:实际和形式参数列表的长度不同。

编译错误2:类SafeConstructor中的构造函数SafeConstructor不能应用于给定类型;必需:LoaderOptionsfound:noargumentsreason:实际和形式参数列表的长度不同。

java gradle compiler-errors yaml snakeyaml
1个回答
0
投票

在 SnakeYAML 2.x 中,RepresenterSafeConstructor 类不再包含默认的无参数构造函数。 Representer 的构造函数需要一个

DumperOptions
对象,而 SafeConstructor 的构造函数需要一个
LoaderOptions
对象。一旦通过这些,编译错误就会得到解决。代码可能如下所示:

private Yaml yaml(){
    DumperOptions dumperOptions = new DumperOptions();
    dumperOptions.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
    LoaderOptions loaderOptions = new LoaderOptions();

    return new Yaml(new LogConstructor(loaderOptions), new LogRepresenter(dumperOptions), dumperOptions);
}

private class LogRepresenter extends Representer {
    public LogRepresenter(DumperOptions options) {
        super(options);

        // Existing code
    }
}

private class LogConstructor extends SafeConstructor {
    public LogConstructor(LoaderOptions loaderOptions) {
        super(loaderOptions);

        // Existing code
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.