Open sergeykad opened 8 years ago
Yeah, the relocation code is ported from Maven Shade which exhibits this same problem: https://issues.apache.org/jira/browse/MSHADE-156 https://issues.apache.org/jira/browse/MSHADE-153
I'll have to think about how best to tackle this. Those tickets have been open for 3 years and they haven't come up with a better solution.
So, this might take a while for me to get something I'm happy with.
I see. Will not ability to exclude classes from this constants substitution solve the issue? Maybe it is not a perfect solution, but it should work in vast majority of cases.
Are there updates on this issue? Is there any workaround for it?
I'm having a similar issue, but it's worse because the strings in question are very clearly NOT package names - they just happen to start with something that could be a package name.
The package is "redis" (the root package of the Jedis client - it's nonstandard, but unfortunately that's what they chose) and the string is a Redis URL string, "redis://localhost:6379". When I shade the Jedis dependency using a prefix of "xxx.shaded", my string becomes "xxx/shaded/redis://localhost:6379". Surely it ought to be possible to know that that wasn't a class/package path, given the double slash.
I see two ways of addressing this that I would be happy to accept PRs for. 1) change the relocation code to do an explicit match of the String against the JVM spec for package names. We’d have to be careful about perf here, perhaps we can only eval against the pattern when the value we are looking to replace is a String (an not a class declaration or package statement) 2) extend the relocation classes to also accept a set of exclude patterns which can be used to skip certain matches. (This could actually be how the first option is implemented with the default set configured to have patterns that match the JVM spec)
I think 2 sounds good— someone's inevitably going to have some strings in their code that will look like valid class names but aren't (the original reporter of this issue had some).
That would be super helpful. We're doing a Gradle plugin that generates code so it contains a lot of Strings
that look exactly like package names... Because well, they actually are package names! And renaming them will break at runtime. For our use cases, I would actually prefer to have a set of include
patterns than excludes
since there is very little use of reflection.
Ultimately, something like GraalVM native image reflection support would be nice albeit considerably more work
I am facing a similar problem: in my build.gradle I have the following:
relocate 'io.netty','thirdparty.io.netty'
I found string literals affected by this shading which caused some runtime errors with the netty dependency.
The following string literal is defined in the original dependency: String staticLibName = "netty_tcnative"
In the shaded jar, this string literal is changed to: String staticLibName = "thirdparty.netty_tcnative";
Is there any way I can prevent this behavior of changing the string literals?
Based on previous responses, it sounds like a workaround won't be implemented until someone contributes a PR.
@johnrengelman can you give more details where that was fixed?
I am still experiencing this bug with my project, which uses Gradle 7.5.1 and Shadow 7.1.2.
Hi folks,
Joining the party late :)
I'm having a similar/same issue trying to relocate google-cloud-logging
with a config like this:
plugins {
id 'com.github.johnrengelman.shadow' version '7.1.2'
}
dependencies {
implementation("com.google.cloud:google-cloud-logging:${googleCloudLoggingVersion}")
}
def shadedPrefix = 'com.mycompany.common.internal.shade.gcloud'
shadowJar {
relocate 'com', "${shadedPrefix}.com"
relocate 'io', "${shadedPrefix}.io"
relocate 'javax.annotation', "${shadedPrefix}.javax.annotation"
relocate 'org', "${shadedPrefix}.org"
archiveClassifier.set('')
mergeServiceFiles()
}
With this I ended up having strings like /computeMetadata/v1/instance/service-accounts/default/token
being renamed to /com/mycompany/common/internal/shade/gcloud/computeMetadata/v1/instance/service-accounts/default/token
, which breaks GCE authentication.
I believe this is the exact same problem (maybe more like this), so just adding more info for future reference.
Having a similar issue here
public static final String ITEMS_KEY = "items";
is interpreted as
public static final String ITEMS_KEY = "xxx.shaded.items";
I am curious though when is this going to be triggered; I tried excluding the package containing this static field but it did not work
relocate ('xxx', 'xxx.shaded') {
exclude 'xxx.yyy'
}
Shadow Version 1.2.3
Gradle Version 2.14
Expected Behavior: There will be an option to control this behavior, preferably using filters
Actual Behavior: All constants are changed
For example Before Shadow:
public static final String AttributePrefix = "org.mypackage";
After Shadowpublic static final String AttributePrefix = "shadow.mypackage";