@@ -80,9 +80,23 @@ ext.versions = [
8080 " jedis" : " 2.9.0"
8181]
8282
83- // Add dependencies to "libraries.internal" that are not exposed in our public API. These
84- // will be completely omitted from the "thin" jar, and will be embedded with shaded names
85- // in the other two SDK jars.
83+ // Add dependencies to "libraries.internal" that we use internally but do not expose in
84+ // our public API. Putting dependencies here has the following effects:
85+ //
86+ // 1. Those classes will be embedded in the default uberjar
87+ // (launchdarkly-java-server-sdk-n.n.n.jar), and also in the "all" jar
88+ // (launchdarkly-java-server-sdk-n.n.n.jar).
89+ //
90+ // 2. The classes are renamed (shaded) within those jars, and all references to them are
91+ // updated to use the shaded names.
92+ //
93+ // 3. The "thin" jar does not contain those classes, and references to them from the code
94+ // in the "thin" jar are *not* renamed. If an application is using the "thin" jar, it is
95+ // expected to provide those classes on its classpath.
96+ //
97+ // 4. They do not appear as dependences in pom.xml.
98+ //
99+ // 5. They are not declared as package imports or package exports in OSGI manifests.
86100//
87101// Note that Gson is included here but Jackson is not, even though there is some Jackson
88102// helper code in java-sdk-common. The reason is that the SDK always needs to use Gson for
@@ -104,7 +118,18 @@ libraries.internal = [
104118]
105119
106120// Add dependencies to "libraries.external" that are exposed in our public API, or that have
107- // global state that must be shared between the SDK and the caller.
121+ // global state that must be shared between the SDK and the caller. Putting dependencies
122+ // here has the following effects:
123+ //
124+ // 1. They are embedded only in the "all" jar.
125+ //
126+ // 2. They are not renamed/shaded, and references to them (in any jar) are not modified.
127+ //
128+ // 3. They *do* appear as dependencies in pom.xml.
129+ //
130+ // 4. In OSGi manifests, they are declared as package imports-- and, in the "all" jar,
131+ // also as package exports (i.e. it provides them if a newer version is not available
132+ // from an import).
108133libraries. external = [
109134 " org.slf4j:slf4j-api:${ versions.slf4j} "
110135]
@@ -114,6 +139,15 @@ libraries.external = [
114139// they are already in the application classpath; we do not want show them as a dependency
115140// because that would cause them to be pulled in automatically in all builds. The reason
116141// we need to even mention them here at all is for the sake of OSGi optional import headers.
142+ // Putting dependencies here has the following effects:
143+ //
144+ // 1. They are not embedded in any of our jars.
145+ //
146+ // 2. References to them (in any jar) are not modified.
147+ //
148+ // 3. They do not appear as dependencies in pom.xml.
149+ //
150+ // 4. In OSGi manifests, they are declared as optional package imports.
117151libraries. optional = [
118152 " com.fasterxml.jackson.core:jackson-core:${ versions.jackson} " ,
119153 " com.fasterxml.jackson.core:jackson-databind:${ versions.jackson} "
@@ -135,6 +169,7 @@ configurations {
135169 // "implementation", because "implementation" has special behavior in Gradle that prevents us
136170 // from referencing it the way we do in shadeDependencies().
137171 internal. extendsFrom implementation
172+ external. extendsFrom api
138173 optional
139174 imports
140175}
@@ -145,12 +180,16 @@ dependencies {
145180 testImplementation libraries. test, libraries. internal, libraries. external
146181 optional libraries. optional
147182
183+ internal libraries. internal
184+ external libraries. external
185+
148186 commonClasses " com.launchdarkly:launchdarkly-java-sdk-common:${ versions.launchdarklyJavaSdkCommon} "
149187 commonDoc " com.launchdarkly:launchdarkly-java-sdk-common:${ versions.launchdarklyJavaSdkCommon} :sources"
150188
151- // Unlike what the name might suggest, the "shadow" configuration specifies dependencies that
152- // should *not* be shaded by the Shadow plugin when we build our shaded jars.
153- shadow libraries. external, libraries. optional
189+ // We are *not* using the special "shadow" configuration that the Shadow plugin defines.
190+ // It's meant to provide similar behavior to what we've defined for "external", but it
191+ // also has other behaviors that we don't want (it would cause dependencies to appear in
192+ // pom.xml and also in a Class-Path attribute).
154193
155194 imports libraries. external
156195}
@@ -167,6 +206,11 @@ task generateJava(type: Copy) {
167206 filter(org.apache.tools.ant.filters.ReplaceTokens , tokens : [VERSION : version. toString()])
168207}
169208
209+ tasks. compileJava {
210+ // See note in build-shared.gradle on the purpose of "privateImplementation"
211+ classpath = configurations. internal + configurations. external
212+ }
213+
170214compileJava. dependsOn ' generateJava'
171215
172216jar {
@@ -190,6 +234,8 @@ shadowJar {
190234 // No classifier means that the shaded jar becomes the default artifact
191235 classifier = ' '
192236
237+ configurations = [ project. configurations. internal ]
238+
193239 dependencies {
194240 exclude(dependency(' org.slf4j:.*:.*' ))
195241 }
@@ -220,15 +266,17 @@ task shadowJarAll(type: com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJ
220266 group = " shadow"
221267 description = " Builds a Shaded fat jar including SLF4J"
222268 from(project. convention. getPlugin(JavaPluginConvention ). sourceSets. main. output)
223- configurations = [project. configurations. runtimeClasspath]
269+
270+ configurations = [ project. configurations. internal, project. configurations. external ]
224271
225272 exclude(' META-INF/INDEX.LIST' , ' META-INF/*.SF' , ' META-INF/*.DSA' , ' META-INF/*.RSA' )
226273 exclude ' **/*.kotlin_metadata'
227274 exclude ' **/*.kotlin_module'
228275 exclude ' **/*.kotlin_builtins'
229276
230277 dependencies {
231- // Currently we don't need to exclude anything - SLF4J will be embedded, unshaded
278+ // We don't need to exclude anything here, because we want everything to be
279+ // embedded in the "all" jar.
232280 }
233281
234282 // doFirst causes the following steps to be run during Gradle's execution phase rather than the
@@ -313,15 +361,26 @@ def getPackagesInDependencyJar(jarFile) {
313361 }
314362}
315363
316- // Used by shadowJar and shadowJarAll to specify which packages should be shaded. We should
317- // *not* shade any of the dependencies that are specified in the "shadow" configuration,
318- // nor any of the classes from the SDK itself.
364+ // Used by shadowJar and shadowJarAll to specify which packages should be renamed.
365+ //
366+ // The SDK's own packages should not be renamed (even though code in those packages will be
367+ // modified to update any references to classes that are being renamed).
368+ //
369+ // Dependencies that are specified in the "external" configuration should not be renamed.
370+ // These are things that (in some distributions) might be included in our uberjar, but need
371+ // to retain their original names so they can be seen by application code.
372+ //
373+ // Dependencies that are specified in the "optional" configuration should not be renamed.
374+ // These are things that we will not be including in our uberjar anyway, but we want to make
375+ // sure we can reference them by their original names if they are in the application
376+ // classpath (which they may or may not be, since they are optional).
319377//
320378// This depends on our build products, so it can't be executed during Gradle's configuration
321379// phase; instead we have to run it after configuration, with the "afterEvaluate" block below.
322380def shadeDependencies (jarTask ) {
323381 def excludePackages = getAllSdkPackages() +
324- configurations. shadow. collectMany { getPackagesInDependencyJar(it) }
382+ configurations. external. collectMany { getPackagesInDependencyJar(it) } +
383+ configurations. optional. collectMany { getPackagesInDependencyJar(it) }
325384 def topLevelPackages =
326385 configurations. internal. collectMany {
327386 getPackagesInDependencyJar(it). collect { it. contains(" ." ) ? it. substring(0 , it. indexOf(" ." )) : it }
@@ -558,9 +617,8 @@ def pomConfig = {
558617
559618 developers {
560619 developer {
561- id ' jkodumal'
562- name ' John Kodumal'
563- email ' john@launchdarkly.com'
620+ name ' LaunchDarkly SDK Team'
621+ email ' sdks@launchdarkly.com'
564622 }
565623 }
566624
@@ -586,17 +644,22 @@ publishing {
586644 def root = asNode()
587645 root. appendNode(' description' , ' Official LaunchDarkly SDK for Java' )
588646
589- // The following workaround is for a known issue where the Shadow plugin assumes that all
590- // non-shaded dependencies should have "runtime" scope rather than "compile".
591- // https://github.com/johnrengelman/shadow/issues/321
592- // https://github.com/launchdarkly/java-server-sdk/issues/151
593- // Currently there doesn't seem to be any way way around this other than simply hacking the
594- // pom at this point after it has been generated by Shadow. All of the dependencies that
595- // are in the pom at this point should have compile scope.
647+ // Here we need to add dependencies explicitly to the pom. The mechanism
648+ // that the Shadow plugin provides-- adding dependencies to a configuration
649+ // called "shadow"-- is not quite what we want, for the reasons described
650+ // in the comments for "libraries.external" etc. (and also because of
651+ // the known issue https://github.com/johnrengelman/shadow/issues/321).
652+ // So we aren't using that.
653+ if (root. getAt(' dependencies' ) == null ) {
654+ root. appendNode(' dependencies' )
655+ }
596656 def dependenciesNode = root. getAt(' dependencies' ). get(0 )
597- dependenciesNode. each { dependencyNode ->
598- def scopeNode = dependencyNode. getAt(' scope' ). get(0 )
599- scopeNode. setValue(' compile' )
657+ configurations. external. getAllDependencies(). each { dep ->
658+ def dependencyNode = dependenciesNode. appendNode(' dependency' )
659+ dependencyNode. appendNode(' groupId' , dep. group)
660+ dependencyNode. appendNode(' artifactId' , dep. name)
661+ dependencyNode. appendNode(' version' , dep. version)
662+ dependencyNode. appendNode(' scope' , ' compile' )
600663 }
601664
602665 root. children(). last() + pomConfig
@@ -635,7 +698,8 @@ def shouldSkipSigning() {
635698// dependencies of the SDK, so they can be put on the classpath as needed during tests.
636699task exportDependencies (type : Copy , dependsOn : compileJava) {
637700 into " packaging-test/temp/dependencies-all"
638- from configurations. runtimeClasspath. resolvedConfiguration. resolvedArtifacts. collect { it. file }
701+ from (configurations. internal. resolvedConfiguration. resolvedArtifacts. collect { it. file }
702+ + configurations. external. resolvedConfiguration. resolvedArtifacts. collect { it. file })
639703}
640704
641705gitPublish {
0 commit comments