diff --git a/spring-javaformat/pom.xml b/spring-javaformat/pom.xml
index 7d4da3bb..76714b2d 100644
--- a/spring-javaformat/pom.xml
+++ b/spring-javaformat/pom.xml
@@ -36,6 +36,7 @@
spring-javaformat-formatter-eclipse-runtime
spring-javaformat-formatter-eclipse
spring-javaformat-formatter
+ spring-javaformat-formatter-shader
spring-javaformat-formatter-shaded
diff --git a/spring-javaformat/spring-javaformat-formatter-shaded/pom.xml b/spring-javaformat/spring-javaformat-formatter-shaded/pom.xml
index 3adde725..bf9b5299 100644
--- a/spring-javaformat/spring-javaformat-formatter-shaded/pom.xml
+++ b/spring-javaformat/spring-javaformat-formatter-shaded/pom.xml
@@ -48,6 +48,13 @@
org.apache.maven.plugins
maven-shade-plugin
+
+
+ ${project.groupId}
+ spring-javaformat-formatter-shader
+ ${project.version}
+
+
true
true
@@ -71,6 +78,9 @@
io.spring.javaformat.org.osgi
+
+
+
@@ -84,7 +94,6 @@
-
io.spring.javaformat
spring-javaformat-formatter
diff --git a/spring-javaformat/spring-javaformat-formatter-shader/pom.xml b/spring-javaformat/spring-javaformat-formatter-shader/pom.xml
new file mode 100644
index 00000000..608f42bd
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-shader/pom.xml
@@ -0,0 +1,24 @@
+
+
+ 4.0.0
+
+ io.spring.javaformat
+ spring-javaformat
+ 0.0.18-SNAPSHOT
+
+ spring-javaformat-formatter-shader
+ Spring JavaFormat Formatter Shaded
+
+ ${basedir}/../..
+
+
+
+ org.apache.maven.plugins
+ maven-shade-plugin
+ 3.1.0
+ maven-plugin
+
+
+
diff --git a/spring-javaformat/spring-javaformat-formatter-shader/src/main/java/io/spring/javaformat/formatter/shader/PrefsResourceTransformer.java b/spring-javaformat/spring-javaformat-formatter-shader/src/main/java/io/spring/javaformat/formatter/shader/PrefsResourceTransformer.java
new file mode 100644
index 00000000..47ba9843
--- /dev/null
+++ b/spring-javaformat/spring-javaformat-formatter-shader/src/main/java/io/spring/javaformat/formatter/shader/PrefsResourceTransformer.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2017-2020 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * https://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package io.spring.javaformat.formatter.shader;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.OutputStreamWriter;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.jar.JarEntry;
+import java.util.jar.JarOutputStream;
+
+import org.apache.maven.plugins.shade.relocation.Relocator;
+import org.apache.maven.plugins.shade.resource.ResourceTransformer;
+
+/**
+ * {@link ResourceTransformer} to fix formatter preference files.
+ *
+ * @author Phillip Webb
+ */
+public class PrefsResourceTransformer implements ResourceTransformer {
+
+ private final Map> transformedResources = new LinkedHashMap<>();
+
+ @Override
+ public boolean canTransformResource(String resource) {
+ return resource.endsWith("formatter.prefs");
+ }
+
+ @Override
+ public void processResource(String resource, InputStream is, List relocators) throws IOException {
+ List trandformedLines = new ArrayList<>();
+ BufferedReader reader = new BufferedReader(new InputStreamReader(is));
+ String line = reader.readLine();
+ while (line != null) {
+ trandformedLines.add(transformLine(line, relocators));
+ line = reader.readLine();
+ }
+ this.transformedResources.put(resource, trandformedLines);
+ }
+
+ private String transformLine(String line, List relocators) {
+ int splitIndex = line.lastIndexOf('=');
+ if (splitIndex == -1) {
+ return line;
+ }
+ String key = line.substring(0, splitIndex);
+ String value = line.substring(splitIndex + 1);
+ return relocateKey(key, relocators) + "=" + value;
+ }
+
+ private String relocateKey(String key, List relocators) {
+ for (Relocator relocator : relocators) {
+ if (relocator.canRelocateClass(key)) {
+ return relocator.relocateClass(key);
+ }
+ }
+ return key;
+ }
+
+ @Override
+ public boolean hasTransformedResource() {
+ return true;
+ }
+
+ @Override
+ public void modifyOutputStream(JarOutputStream os) throws IOException {
+ for (Map.Entry> entry : this.transformedResources.entrySet()) {
+ write(os, entry.getKey(), entry.getValue());
+ }
+ }
+
+ private void write(JarOutputStream os, String resource, List lines) throws IOException {
+ os.putNextEntry(new JarEntry(resource));
+ BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(os));
+ for (String line : lines) {
+ writer.write(line);
+ writer.write("\n");
+ }
+ writer.flush();
+ }
+
+}