Skip to content

Commit d056c32

Browse files
authored
Additional Dependency updates (#9006)
* Updating dependency management and vulnerable dependencies * Update dependencies to fix vulnerabilities as reported in #8950 * Update our dependency management to make use of some newish gradle features * Add dependency constraints to update transitive dependencies, this allows us to specify versions without making them direct dependencies * Remove most force expressions and replace them where necessary with version strict requirements * Make use of several published bom's to configure consistent dependency versions for platforms like netty and log4j2 * Remove exclude statements that are now handled by variant dependency resolution (like guava android vs jdk) * Exclude the org.bouncycastle:bcprov-jdk15on dependency and replace it with bcprov-jdk18onA This adds an unnecessary testUtilImplementation level dependency on what is really a transitive, but I couldn't get gradle's explicit version replacement to work. replacement logic to work so this is a workaround
1 parent b409f77 commit d056c32

File tree

10 files changed

+132
-89
lines changed

10 files changed

+132
-89
lines changed

build.gradle

Lines changed: 104 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,10 @@ final genomicsdbVersion = System.getProperty('genomicsdb.version','1.5.4')
6969
final bigQueryVersion = System.getProperty('bigQuery.version', '2.35.0')
7070
final bigQueryStorageVersion = System.getProperty('bigQueryStorage.version', '2.47.0')
7171
final guavaVersion = System.getProperty('guava.version', '32.1.3-jre')
72-
final log4j2Version = System.getProperty('log4j2Version', '2.17.1')
73-
final testNGVersion = '7.7.0'
74-
75-
final googleCloudNioDependency = 'com.google.cloud:google-cloud-nio:0.127.8'
72+
final log4j2Version = System.getProperty('log4j2Version', '2.24.1')
73+
final testNGVersion = System.getProperty('testNGVersion', '7.7.0')
74+
final googleCloudNioVersion = System.getProperty('googleCloudNioVersion','0.127.8')
75+
final gklVersion = System.getProperty('gklVersion', '0.8.11')
7676

7777
final baseJarName = 'gatk'
7878
final secondaryBaseJarName = 'hellbender'
@@ -166,27 +166,12 @@ if (versionOverridden) {
166166
}
167167

168168
configurations.configureEach {
169-
resolutionStrategy {
170-
// the snapshot folder contains a dev version of guava, we don't want to use that.
171-
force 'com.google.guava:guava:' + guavaVersion
172-
// force the htsjdk version so we don't get a different one transitively
173-
force 'com.github.samtools:htsjdk:' + htsjdkVersion
174-
force 'com.google.protobuf:protobuf-java:3.25.5'
175-
// force testng dependency so we don't pick up a different version via GenomicsDB
176-
force 'org.testng:testng:' + testNGVersion
177-
force 'org.broadinstitute:barclay:' + barclayVersion
178-
force 'com.twitter:chill_2.12:0.10.0'
179-
force 'org.apache.commons:commons-math3:3.5'
180-
181-
// make sure we don't pick up an incorrect version of the GATK variant of the google-nio library
182-
// via Picard, etc.
183-
force googleCloudNioDependency
184-
185-
force 'com.esotericsoftware:kryo:4.0.0'
186-
}
187169
configurations*.exclude group: 'org.slf4j', module: 'slf4j-jdk14' //exclude this to prevent slf4j complaining about to many slf4j bindings
188170
configurations*.exclude group: 'com.google.guava', module: 'guava-jdk5'
189171
configurations*.exclude group: 'junit', module: 'junit'
172+
173+
//this is excluded and replaced below with a dependency on bcprof-jdk18on which fixes known vulnerabilities
174+
//configurations*.exclude group: 'org.bouncycastle', module: 'bcprov-jdk15on'
190175
}
191176

192177
tasks.withType(JavaCompile).configureEach {
@@ -221,37 +206,47 @@ configurations {
221206
// exclude Hadoop and Spark dependencies, since they are provided when running with Spark
222207
// (ref: http://unethicalblogger.com/2015/07/15/gradle-goodness-excluding-depends-from-shadow.html)
223208
exclude group: 'org.apache.hadoop'
224-
exclude module: 'spark-core_2.12'
209+
exclude module: 'spark-core_2.13'
225210
exclude group: 'org.slf4j'
226211
exclude module: 'jul-to-slf4j'
227212
exclude module: 'javax.servlet'
228213
exclude module: 'servlet-api'
229214
exclude group: 'com.esotericsoftware.kryo'
230-
exclude module: 'spark-mllib_2.12.15'
215+
exclude module: 'spark-mllib_2.13.15'
231216
exclude group: 'org.scala-lang'
232217
exclude module: 'kryo'
233218
}
234219
}
235220

236221
dependencies {
237222

238-
implementation ('org.freemarker:freemarker:2.3.30')
239-
implementation 'org.broadinstitute:barclay:' + barclayVersion
223+
implementation 'org.freemarker:freemarker:2.3.30'
224+
implementation ('org.broadinstitute:barclay'){
225+
version {
226+
strictly barclayVersion
227+
}
228+
}
240229
// Library for configuration:
241230
implementation 'org.aeonbits.owner:owner:1.0.9'
242231

243232
implementation 'com.github.broadinstitute:picard:' + picardVersion
244233
externalSourceConfiguration 'com.github.broadinstitute:picard:' + picardVersion + ':sources'
245-
implementation ('org.genomicsdb:genomicsdb:' + genomicsdbVersion) {
246-
exclude module: 'log4j-api'
247-
exclude module: 'log4j-core'
248-
exclude module: 'htsjdk'
249-
exclude module: 'protobuf-java'
250-
}
234+
235+
implementation 'org.genomicsdb:genomicsdb:' + genomicsdbVersion
251236
implementation 'com.opencsv:opencsv:3.4'
252237
implementation 'com.google.guava:guava:' + guavaVersion
253-
implementation 'com.github.samtools:htsjdk:'+ htsjdkVersion
254-
implementation(googleCloudNioDependency)
238+
239+
implementation ('com.github.samtools:htsjdk'){
240+
version {
241+
strictly htsjdkVersion
242+
}
243+
}
244+
245+
implementation ('com.google.cloud:google-cloud-nio'){
246+
version {
247+
strictly googleCloudNioVersion
248+
}
249+
}
255250

256251
implementation 'com.google.cloud:google-cloud-bigquery:' + bigQueryVersion
257252
implementation 'com.google.cloud:google-cloud-bigquerystorage:' + bigQueryStorageVersion
@@ -263,27 +258,32 @@ dependencies {
263258
// should we want to)
264259
implementation 'com.google.cloud.bigdataoss:gcs-connector:1.9.4-hadoop3'
265260

266-
implementation 'org.apache.logging.log4j:log4j-api:' + log4j2Version
267-
implementation 'org.apache.logging.log4j:log4j-core:' + log4j2Version
261+
implementation platform('org.apache.logging.log4j:log4j-bom:' + log4j2Version)
262+
implementation 'org.apache.logging.log4j:log4j-api'
263+
implementation 'org.apache.logging.log4j:log4j-core'
268264
// include the apache commons-logging bridge that matches the log4j version we use so
269265
// messages that originate with dependencies that use commons-logging (such as jexl)
270266
// are routed to log4j
271-
implementation 'org.apache.logging.log4j:log4j-jcl:' + log4j2Version
267+
implementation 'org.apache.logging.log4j:log4j-jcl'
268+
// these two annotation dependencies
269+
// are needed because log4j-core isn't meant to be included
270+
// at compile time so it doesn't include its own annotations
271+
// https://github.com/apache/logging-log4j2/issues/3110
272+
implementation 'biz.aQute.bnd:biz.aQute.bnd.annotation'
273+
implementation 'org.osgi:org.osgi.annotation.bundle'
274+
272275

273276
implementation 'org.apache.commons:commons-lang3:3.14.0'
274-
implementation 'org.apache.commons:commons-math3:3.6.1'
277+
implementation('org.apache.commons:commons-math3'){
278+
version {
279+
strictly '3.5' // changing this breaks ModelSegmentsIntegrationTests, they're quite brittle
280+
}
281+
because "updating this breaks ModelSegmentsIntegrationTests, they're quite brittle"
282+
}
275283
implementation 'org.hipparchus:hipparchus-stat:2.0'
276284
implementation 'org.apache.commons:commons-collections4:4.4'
277285
implementation 'org.apache.commons:commons-vfs2:2.9.0'
278286
implementation 'org.apache.commons:commons-configuration2:2.10.1'
279-
constraints {
280-
implementation('org.apache.commons:commons-text') {
281-
version {
282-
strictly '1.10.0'
283-
}
284-
because 'previous versions have a nasty vulnerability: https://nvd.nist.gov/vuln/detail/CVE-2022-42889'
285-
}
286-
}
287287

288288
implementation 'org.apache.httpcomponents:httpclient:4.5.13'
289289
implementation 'commons-beanutils:commons-beanutils:1.9.4'
@@ -296,12 +296,11 @@ dependencies {
296296
implementation 'org.broadinstitute:gatk-native-bindings:1.0.0'
297297

298298
implementation 'org.ojalgo:ojalgo:44.0.0'
299-
implementation ('org.ojalgo:ojalgo-commons-math3:1.0.0') {
299+
implementation('org.ojalgo:ojalgo-commons-math3:1.0.0'){
300300
exclude group: 'org.apache.commons'
301301
}
302302

303-
// TODO: migrate to mllib_2.12.15?
304-
implementation ('org.apache.spark:spark-mllib_2.12:' + sparkVersion) {
303+
implementation ('org.apache.spark:spark-mllib_2.13:' + sparkVersion) {
305304
// JUL is used by Google Dataflow as the backend logger, so exclude jul-to-slf4j to avoid a loop
306305
exclude module: 'jul-to-slf4j'
307306
exclude module: 'javax.servlet'
@@ -312,28 +311,29 @@ dependencies {
312311
implementation 'org.jgrapht:jgrapht-core:1.1.0'
313312
implementation 'org.jgrapht:jgrapht-io:1.1.0'
314313

315-
implementation('org.disq-bio:disq:' + disqVersion)
316-
implementation('org.apache.hadoop:hadoop-client:' + hadoopVersion) // should be a 'provided' dependency
317-
implementation('com.github.jsr203hadoop:jsr203hadoop:1.0.3')
314+
implementation 'org.disq-bio:disq:' + disqVersion
315+
implementation 'org.apache.hadoop:hadoop-client:' + hadoopVersion // should be a 'provided' dependency
316+
implementation 'com.github.jsr203hadoop:jsr203hadoop:1.0.3'
318317

319-
implementation('org.apache.orc:orc:1.6.5')
320-
implementation('de.javakaffee:kryo-serializers:0.45') {
321-
exclude module: 'kryo' // use Spark's version
318+
implementation 'org.apache.orc:orc:1.6.5'
319+
implementation 'de.javakaffee:kryo-serializers:0.45'
320+
implementation ('com.esotericsoftware:kryo'){
321+
version {
322+
strictly '4.+' // we're not compatible with kryo 5+
323+
}
322324
}
323325

324326
// Dependency change for including MLLib
325-
implementation('org.objenesis:objenesis:1.2')
326-
testImplementation('org.objenesis:objenesis:2.1')
327+
implementation 'org.objenesis:objenesis:1.2'
328+
testImplementation 'org.objenesis:objenesis:2.1'
327329

328330
// Comment the next lines to disable native code proxies in Spark MLLib
329-
implementation('com.github.fommil.netlib:netlib-native_ref-osx-x86_64:1.1:natives')
330-
implementation('com.github.fommil.netlib:netlib-native_ref-linux-x86_64:1.1:natives')
331-
implementation('com.github.fommil.netlib:netlib-native_system-linux-x86_64:1.1:natives')
332-
implementation('com.github.fommil.netlib:netlib-native_system-osx-x86_64:1.1:natives')
331+
implementation 'com.github.fommil.netlib:netlib-native_ref-osx-x86_64:1.1:natives'
332+
implementation 'com.github.fommil.netlib:netlib-native_ref-linux-x86_64:1.1:natives'
333+
implementation 'com.github.fommil.netlib:netlib-native_system-linux-x86_64:1.1:natives'
334+
implementation 'com.github.fommil.netlib:netlib-native_system-osx-x86_64:1.1:natives'
333335

334-
implementation('com.intel.gkl:gkl:0.8.11') {
335-
exclude module: 'htsjdk'
336-
}
336+
implementation 'com.intel.gkl:gkl:' + gklVersion
337337

338338
implementation 'org.broadinstitute:gatk-bwamem-jni:1.0.4'
339339
implementation 'org.broadinstitute:gatk-fermilite-jni:1.2.0'
@@ -344,12 +344,50 @@ dependencies {
344344
implementation 'org.xerial:sqlite-jdbc:3.44.1.0'
345345

346346
// natural sort
347-
implementation('net.grey-panther:natural-comparator:1.1')
348-
implementation('com.fasterxml.jackson.module:jackson-module-scala_2.12:2.9.8')
347+
implementation 'net.grey-panther:natural-comparator:1.1'
348+
implementation 'com.fasterxml.jackson.module:jackson-module-scala_2.13:2.9.8'
349+
350+
/********* Update transitive dependencies that have known vulnerabilities in this section *******/
351+
constraints {
352+
// all of these constraints are here to force upgrades from lower versions of these libraries which are included
353+
// as transitive dependencies
354+
// once the libraries that make use of these move forward we can remove these constraints
355+
356+
implementation 'com.google.protobuf:protobuf-java:3.25.5'
357+
implementation 'dnsjava:dnsjava:3.6.0'
358+
implementation 'org.apache.commons:commons-compress:1.26.0'
359+
implementation 'org.apache.ivy:ivy:2.5.2'
360+
implementation 'org.apache.commons:commons-text:1.10.0' because 'of https://nvd.nist.gov/vuln/detail/CVE-2022-42889'
361+
implementation 'ch.qos.logback:logback-classic:1.4.14'
362+
implementation 'ch.qos.logback:logback-core:1.4.14'
363+
implementation 'org.apache.avro:avro:1.12.0'
364+
implementation 'io.airlift:aircompressor:0.27'
365+
implementation 'org.scala-lang:scala-library:2.13.14'
366+
implementation 'com.nimbusds:nimbus-jose-jwt:9.41.2'
367+
implementation 'org.codehaus.janino:janino:3.1.12'
368+
implementation 'org.apache.zookeeper:zookeeper:3.9.2'
369+
implementation 'org.jetbrains.kotlin:kotlin-stdlib:1.9.25'
370+
implementation 'com.squareup.okio:okio:3.9.1'
371+
implementation 'org.codehaus.jettison:jettison:1.5.4'
372+
implementation 'org.eclipse.jetty:jetty-http:9.4.56.v20240826'
373+
implementation 'org.xerial.snappy:snappy-java:1.1.10.4'
374+
}
375+
376+
//use netty bom to enforce same netty version
377+
//this upgrades all transitive netty dependencies without adding a direct dependency on netty
378+
implementation platform('io.netty:netty-bom:4.1.114.Final')
379+
380+
/************************************************************************************************/
381+
349382

350383
testUtilsImplementation sourceSets.main.output
351384
testUtilsImplementation 'org.testng:testng:' + testNGVersion
352385
testUtilsImplementation 'org.apache.hadoop:hadoop-minicluster:' + hadoopVersion
386+
//this is a replacement for the transitive dependency of minicluster: bcprov-jdk15on:1.70.0
387+
// which is excluded for security purposes
388+
//this causes this to act as direct dependency of ours but we don't actually rely on it except as a transitive
389+
testUtilsImplementation 'org.bouncycastle:bcprov-jdk18on:1.78.1' //
390+
353391

354392
testImplementation sourceSets.testUtils.output
355393

src/main/java/org/broadinstitute/hellbender/engine/spark/RangePartitionCoalescer.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,19 @@
44
import org.apache.spark.rdd.PartitionCoalescer;
55
import org.apache.spark.rdd.PartitionGroup;
66
import org.apache.spark.rdd.RDD;
7-
import scala.collection.JavaConversions;
87
import scala.collection.Seq;
9-
8+
import scala.jdk.javaapi.CollectionConverters;
9+
import java.io.Serial;
1010
import java.io.Serializable;
1111
import java.util.Arrays;
1212
import java.util.List;
1313

1414
/**
1515
* A {@link PartitionCoalescer} that allows a range of partitions to be coalesced into groups.
1616
*/
17-
class RangePartitionCoalescer implements PartitionCoalescer, Serializable, scala.Serializable {
17+
class RangePartitionCoalescer implements PartitionCoalescer, Serializable {
1818

19+
@Serial
1920
private static final long serialVersionUID = 1L;
2021

2122
private List<Integer> maxEndPartitionIndexes;
@@ -45,7 +46,7 @@ public PartitionGroup[] coalesce(int maxPartitions, RDD<?> parent) {
4546
PartitionGroup group = new PartitionGroup(preferredLocation);
4647
List<Partition> partitionsInGroup =
4748
partitions.subList(i, maxEndPartitionIndexes.get(i) + 1);
48-
group.partitions().append(JavaConversions.asScalaBuffer(partitionsInGroup));
49+
group.partitions().addAll(CollectionConverters.asScala(partitionsInGroup).toList());
4950
groups[i] = group;
5051
}
5152
return groups;

src/main/java/org/broadinstitute/hellbender/tools/spark/pathseq/PSBuildReferenceTaxonomyUtils.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -313,13 +313,13 @@ public static BufferedReader getBufferedReaderTarGz(final String tarPath, final
313313
try {
314314
InputStream result = null;
315315
final TarArchiveInputStream tarStream = new TarArchiveInputStream(new GZIPInputStream(new FileInputStream(tarPath)));
316-
TarArchiveEntry entry = tarStream.getNextTarEntry();
316+
TarArchiveEntry entry = tarStream.getNextEntry();
317317
while (entry != null) {
318318
if (entry.getName().equals(fileName)) {
319319
result = tarStream;
320320
break;
321321
}
322-
entry = tarStream.getNextTarEntry();
322+
entry = tarStream.getNextEntry();
323323
}
324324
if (result == null) {
325325
throw new UserException.BadInput("Could not find file " + fileName + " in tarball " + tarPath);

src/main/java/org/broadinstitute/hellbender/tools/spark/sv/StructuralVariationDiscoveryPipelineSpark.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,10 @@
4141
import org.broadinstitute.hellbender.utils.io.IOUtils;
4242
import org.broadinstitute.hellbender.utils.read.GATKRead;
4343
import org.broadinstitute.hellbender.utils.read.SAMRecordToGATKReadAdapter;
44-
import scala.Serializable;
4544

4645
import java.io.IOException;
46+
import java.io.Serial;
47+
import java.io.Serializable;
4748
import java.nio.file.Paths;
4849
import java.util.List;
4950
import java.util.Set;
@@ -364,6 +365,7 @@ private static List<VariantContext> processEvidenceTargetLinks(List<VariantConte
364365
// parser ==========================================================================================================
365366

366367
public static final class InMemoryAlignmentParser extends AlignedContigGenerator implements Serializable {
368+
@Serial
367369
private static final long serialVersionUID = 1L;
368370

369371
private final JavaSparkContext ctx;

src/main/java/org/broadinstitute/hellbender/tools/spark/sv/utils/ComplexityPartitioner.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22

33
import org.apache.spark.Partitioner;
44

5+
import java.io.Serial;
56
import java.util.Arrays;
67

78
/** A Spark Partitioner that puts tasks with greater complexities into earlier partitions. */
89
public final class ComplexityPartitioner extends Partitioner {
10+
@Serial
911
private static final long serialVersionUID = 1L;
1012
private final int[] partitions;
1113

src/main/java/org/broadinstitute/hellbender/utils/gcs/BucketUtils.java

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package org.broadinstitute.hellbender.utils.gcs;
22

3-
import com.google.cloud.hadoop.gcsio.GoogleCloudStorageFileSystem;
43
import com.google.cloud.storage.BlobInfo;
54
import com.google.cloud.storage.HttpMethod;
65
import com.google.cloud.storage.Storage;
@@ -46,7 +45,7 @@
4645
* Utilities for dealing with google buckets.
4746
*/
4847
public final class BucketUtils {
49-
public static final String GCS_PREFIX = GoogleCloudStorageFileSystem.SCHEME + "://";
48+
public static final String GCS_PREFIX = CloudStorageFileSystem.URI_SCHEME + "://";
5049
public static final String HTTP_PREFIX = HttpFileSystemProvider.SCHEME + "://";
5150
public static final String HTTPS_PREFIX = HttpsFileSystemProvider.SCHEME +"://";
5251
public static final String HDFS_SCHEME = "hdfs";
@@ -74,7 +73,7 @@ public static boolean isGcsUrl(final String path) {
7473
*/
7574
public static boolean isGcsUrl(final GATKPath pathSpec) {
7675
Utils.nonNull(pathSpec);
77-
return pathSpec.getScheme().equals(GoogleCloudStorageFileSystem.SCHEME);
76+
return pathSpec.getScheme().equals(CloudStorageFileSystem.URI_SCHEME);
7877
}
7978

8079
/**
@@ -97,7 +96,7 @@ public static boolean isEligibleForPrefetching(final java.nio.file.Path path) {
9796

9897
private static boolean isEligibleForPrefetching(final String scheme){
9998
return scheme != null
100-
&& (scheme.equals(GoogleCloudStorageFileSystem.SCHEME)
99+
&& (scheme.equals(CloudStorageFileSystem.URI_SCHEME)
101100
|| scheme.equals(HttpFileSystemProvider.SCHEME)
102101
|| scheme.equals(HttpsFileSystemProvider.SCHEME));
103102
}

src/main/java/org/broadinstitute/hellbender/utils/io/IOUtils.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -468,7 +468,7 @@ private static void extractFilesFromArchiveStream(final TarArchiveInputStream ar
468468

469469
// Go through the archive and get the entries:
470470
TarArchiveEntry entry;
471-
while ((entry = archiveStream.getNextTarEntry()) != null) {
471+
while ((entry = archiveStream.getNextEntry()) != null) {
472472

473473
logger.info("Extracting file: " + entry.getName());
474474

@@ -549,7 +549,7 @@ private static void addToTar(TarArchiveOutputStream out, File file, String dir)
549549
if (file.isFile()){
550550
out.putArchiveEntry(new TarArchiveEntry(file, entry));
551551
try (FileInputStream in = new FileInputStream(file)){
552-
org.apache.commons.compress.utils.IOUtils.copy(in, out);
552+
org.apache.commons.io.IOUtils.copy(in, out);
553553
}
554554
out.closeArchiveEntry();
555555
} else if (file.isDirectory()) {

0 commit comments

Comments
 (0)