【问题标题】:static variables behave differently in maven jars and eclipse runnable jars静态变量在 maven jar 和 eclipse 可运行 jar 中的行为不同
【发布时间】:2019-11-25 00:18:59
【问题描述】:

我需要使用在外部类中初始化的变量才能在内部类中使用。所以我使用了静态变量。这也是 Flink 应用程序。

当构建为 eclipse-export-runnable jar 时——它工作正常——变量的状态保留

当构建为 maven 或 eclipse-export-jar - 它失败 - 变量状态丢失

FileMonitorWrapper.fileInputDir--values 是 "" 并且不获取传递的值。

听起来很奇怪..任何想法

static transient String fileInputDir="";
static transient String fileArchiveDir="";
@SuppressWarnings("serial")
public DataStream<String> ScanDirectoryForFile(String inputDir, String inputFilePattern,String archiveDir, StreamExecutionEnvironment env) {
    try {
        FileMonitorWrapper.fileArchiveDir = archiveDir;
        FileMonitorWrapper.fileInputDir = inputDir;
                    filteredDirFiles = dirFiles.filter(new FileMapper());
    .
    .
    .
    }
    }



     @SuppressWarnings("serial")
 static class FileMapper implements     FilterFunction<TimestampedFileInputSplit>{
      @Override
  public boolean filter(TimestampedFileInputSplit value) throws Exception {

    if(value.toString().contains("done")) 
        FileMonitorWrapper.doneFound = true;
    if(value.toString().contains("dat"));
        FileMonitorWrapper.datFound = true;
    if(FileMonitorWrapper.datFound && FileMonitorWrapper.doneFound) {
        try {
        if(value.getPath().toString().contains("done")) {
            Files.move(Paths.get(FileMonitorWrapper.fileInputDir+"\\"+value.getPath().getName()),
                    Paths.get(FileMonitorWrapper.fileArchiveDir+"\\"+value.getPath().getName()));
        }
        }catch(Exception e){
                e.printStackTrace();
        }

        return (!value.toString().contains("done"));
    }
    else 
        return false;
  }
}

}

【问题讨论】:

  • “听起来很奇怪..任何想法” - 这是不可能的。一定有别的解释。

标签: java eclipse maven jar apache-flink


【解决方案1】:

一般来说,POJO 的序列化不会捕获静态变量的状态。据我了解,Flink 序列化也不例外。

所以当你说静态变量 state 在某些情况下是“保留的”时,我认为你误解了证据。其他东西是保留静态变量的状态,或者它们被初始化为在“之前”和“之后”情况下碰巧相同的值。


为什么我对此如此确定?问题是序列化静态变量没有多大意义。考虑一下这个

public class Cat {
    private static List<Cat> allCats = new ArrayList<>();
    private String name;
    private String colour;

    public Cat(...) {
        ...
        allCats.add(this);
    }
    ...
}

Cat fluffy = new Cat("fluffy", ...);
Cat claus = new Cat("claus", ...);

如果Cat的静态字段被序列化:

  1. 每次串行流包含 Cat 时,它将(必须)包含到目前为止创建的所有猫。

  2. 每当我反序列化包含Cat 的流时,我还需要反序列化ArrayList&lt;Cat&gt;。我该怎么办?

    • 我会用它覆盖allCats 吗? (然后忘记其他猫了?)
    • 我要把它扔掉吗?
    • 我是否尝试合并列表? (怎么做?什么语义?我有两只猫叫“毛茸茸”吗?)

基本上,这个场景没有语义可以很好地解决一般情况。 (通用)解决方案是不序列化 static 变量。

【讨论】:

    猜你喜欢
    • 2020-12-02
    • 2014-03-10
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 2021-08-14
    • 1970-01-01
    • 2013-02-21
    • 2023-03-14
    相关资源
    最近更新 更多