Java 你应该隐藏你的依赖吗?

Java 你应该隐藏你的依赖吗?,java,apache-spark,gradle,dependencies,Java,Apache Spark,Gradle,Dependencies,对于我的工作,我每天都使用Spark。其中一个问题来自依赖冲突。我忍不住想,如果人们发布已经着色到自己名称空间的jar,它们都会消失 对于内部JAR,我正在考虑对所有依赖项执行此操作。除了一点点工作,我认为这是个好主意。是否有我遗漏的缺点/风险?阴影处理会消除一些问题,但会出现新的问题。一个问题是,您剥夺了用户使用与着色中使用的版本不同(修补)版本的依赖项的机会。 但着色的主要风险是着色类最终会暴露给客户 假设你有两个依赖项a,b,每个着色log4j。因此,当包含a和b时,在编译/运行时类路径上

对于我的工作,我每天都使用
Spark
。其中一个问题来自依赖冲突。我忍不住想,如果人们发布已经着色到自己名称空间的jar,它们都会消失


对于内部JAR,我正在考虑对所有依赖项执行此操作。除了一点点工作,我认为这是个好主意。是否有我遗漏的缺点/风险?

阴影处理会消除一些问题,但会出现新的问题。一个问题是,您剥夺了用户使用与着色中使用的版本不同(修补)版本的依赖项的机会。 但着色的主要风险是着色类最终会暴露给客户

假设你有两个依赖项a,b,每个着色log4j。因此,当包含a和b时,在编译/运行时类路径上会得到类a.shade.log4j.Logger(v1.3)和类b.shade.log4j.Logger(1.4)。您可以拥有自己的log4j.Logger(1.5)

然后,您希望在运行时对系统中的所有记录器执行一些操作,但突然之间,您在运行时得到了许多不同的记录器类和类版本


因此,只有当您能够确保客户端不会通过库的API看到着色类的任何实例时,着色才没有风险。但这很难保证。也许对于Java9中的模块,问题会小一些,但即使在类路径上只有一个已知版本的任何类,也比使用相同名称但不同版本的着色类的广泛混合更容易调试/管理。

显然存在膨胀问题。如果包含10个库,每个库都有自己的
Spark
版本,则
Spark
jar的大小将是使用依赖项解析选择单个版本的10倍。如果您将所有版本发布到存储库(如nexus),那么您可能会发现额外的JAR开始在nexus上占用相当多的磁盘空间。这个问题是一个坑,底部是一个实现——任何适合您的都是最适合您的。