diff --git a/packaging-test/test-app/src/main/java/com/launchdarkly/shaded/com/newrelic/api/agent/NewRelic.java b/packaging-test/test-app/src/main/java/com/launchdarkly/shaded/com/newrelic/api/agent/NewRelic.java new file mode 100644 index 000000000..83bae9f3b --- /dev/null +++ b/packaging-test/test-app/src/main/java/com/launchdarkly/shaded/com/newrelic/api/agent/NewRelic.java @@ -0,0 +1,9 @@ +package com.launchdarkly.shaded.com.newrelic.api.agent; + +// Test to verify fix for https://github.com/launchdarkly/java-server-sdk/issues/171 +public class NewRelic { + public static void addCustomParameter(String name, String value) { + System.out.println("NewRelic class reference was shaded! Test app loaded " + NewRelic.class.getName()); + System.exit(1); // forces test failure + } +} diff --git a/packaging-test/test-app/src/main/java/com/newrelic/api/agent/NewRelic.java b/packaging-test/test-app/src/main/java/com/newrelic/api/agent/NewRelic.java new file mode 100644 index 000000000..5b106c460 --- /dev/null +++ b/packaging-test/test-app/src/main/java/com/newrelic/api/agent/NewRelic.java @@ -0,0 +1,8 @@ +package com.newrelic.api.agent; + +// Test to verify fix for https://github.com/launchdarkly/java-server-sdk/issues/171 +public class NewRelic { + public static void addCustomParameter(String name, String value) { + System.out.println("NewRelic class reference was correctly resolved without shading"); + } +} diff --git a/packaging-test/test-app/src/main/java/testapp/TestApp.java b/packaging-test/test-app/src/main/java/testapp/TestApp.java index f56f1207e..200b2f4e2 100644 --- a/packaging-test/test-app/src/main/java/testapp/TestApp.java +++ b/packaging-test/test-app/src/main/java/testapp/TestApp.java @@ -18,6 +18,9 @@ public static void main(String[] args) throws Exception { // that provides its own copy of Gson). JsonPrimitive x = new JsonPrimitive("x"); + // Also do a flag evaluation, to ensure that it calls NewRelicReflector.annotateTransaction() + client.boolVariation("flag-key", new LDUser("user-key"), false); + System.out.println("@@@ successfully created LD client @@@"); } } \ No newline at end of file diff --git a/src/main/java/com/launchdarkly/client/NewRelicReflector.java b/src/main/java/com/launchdarkly/client/NewRelicReflector.java index 8a9c1c0cb..91a09c52c 100644 --- a/src/main/java/com/launchdarkly/client/NewRelicReflector.java +++ b/src/main/java/com/launchdarkly/client/NewRelicReflector.java @@ -1,5 +1,7 @@ package com.launchdarkly.client; +import com.google.common.base.Joiner; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -13,17 +15,24 @@ final class NewRelicReflector { private static final Logger logger = LoggerFactory.getLogger(NewRelicReflector.class); - static { try { - newRelic = Class.forName("com.newrelic.api.agent.NewRelic"); + newRelic = Class.forName(getNewRelicClassName()); addCustomParameter = newRelic.getDeclaredMethod("addCustomParameter", String.class, String.class); } catch (ClassNotFoundException | NoSuchMethodException e) { logger.info("No NewRelic agent detected"); } } - static void annotateTransaction(String featureKey, String value) { + static String getNewRelicClassName() { + // This ungainly logic is a workaround for the overly aggressive behavior of the Shadow plugin, which + // will transform any class or package names passed to Class.forName() if they are string literals; + // it will even transform the string "com". + String com = Joiner.on("").join(new String[] { "c", "o", "m" }); + return Joiner.on(".").join(new String[] { com, "newrelic", "api", "agent", "NewRelic" }); + } + + static void annotateTransaction(String featureKey, String value) { if (addCustomParameter != null) { try { addCustomParameter.invoke(null, featureKey, value); @@ -32,6 +41,5 @@ static void annotateTransaction(String featureKey, String value) { logger.debug(e.toString(), e); } } - } - + } }