Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(FeatureClassLoader): support class loading of Java 9+ #426

Merged
merged 5 commits into from Aug 7, 2019
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGES.md
Expand Up @@ -7,6 +7,8 @@ You might be looking for:

### Version 1.25.0-SNAPSHOT - TBD (javadoc [lib](https://diffplug.github.io/spotless/javadoc/spotless-lib/snapshot/) [lib-extra](https://diffplug.github.io/spotless/javadoc/spotless-lib-extra/snapshot/), [snapshot repo](https://oss.sonatype.org/content/repositories/snapshots/com/diffplug/spotless/))

* Fixes class loading issue with Java 9+ ([#426](https://github.com/diffplug/spotless/pull/426)).

### Version 1.24.0 - July 29th 2018 (javadoc [lib](https://diffplug.github.io/spotless/javadoc/spotless-lib/1.24.0/) [lib-extra](https://diffplug.github.io/spotless/javadoc/spotless-lib-extra/1.24.0/), artifact [lib]([jcenter](https://bintray.com/diffplug/opensource/spotless-lib), [lib-extra]([jcenter](https://bintray.com/diffplug/opensource/spotless-lib-extra)))

* Updated default eclipse-wtp from 4.8.0 to 4.12.0 ([#423](https://github.com/diffplug/spotless/pull/423)).
Expand Down
26 changes: 25 additions & 1 deletion lib/src/main/java/com/diffplug/spotless/FeatureClassLoader.java
Expand Up @@ -22,6 +22,8 @@
import java.util.List;
import java.util.Objects;

import javax.annotation.Nullable;

/**
* This class loader is used to load classes of Spotless features from a search
* path of URLs.<br/>
Expand Down Expand Up @@ -59,7 +61,7 @@ class FeatureClassLoader extends URLClassLoader {
*/

FeatureClassLoader(URL[] urls, ClassLoader buildToolClassLoader) {
super(urls, null);
super(urls, getParentClassLoader());
Objects.requireNonNull(buildToolClassLoader);
this.buildToolClassLoader = buildToolClassLoader;
}
Expand All @@ -74,4 +76,26 @@ protected Class<?> findClass(String name) throws ClassNotFoundException {
return super.findClass(name);
}

/**
* Making spotless Java 9+ compatible. In Java 8 (and minor) the bootstrap
* class loader saw every platform class. In Java 9+ it was changed so the
* bootstrap class loader does not see all classes anymore. This might lead
* to ClassNotFoundException in formatters (e.g. freshmark).
*
* @return <code>null</code> on Java 8 (and minor), otherwise <code>PlatformClassLoader</code>
*/
@Nullable
private static ClassLoader getParentClassLoader() {
if (JavaVersion.getMajorVersion() >= 9) {
try {
return (ClassLoader) ClassLoader.class.getMethod("getPlatformClassLoader").invoke(null);
bender316 marked this conversation as resolved.
Show resolved Hide resolved
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new RuntimeException(e);
}
} else {
return null;
}
}
bender316 marked this conversation as resolved.
Show resolved Hide resolved
}
53 changes: 53 additions & 0 deletions lib/src/main/java/com/diffplug/spotless/JavaVersion.java
@@ -0,0 +1,53 @@
/*
* Copyright 2016 DiffPlug
*
* 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
*
* http://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 com.diffplug.spotless;

/**
* Helper class providing Java version information
*
*/
public final class JavaVersion {
bender316 marked this conversation as resolved.
Show resolved Hide resolved

private static final String JAVA_VERSION;

private static final int MAJOR_VERSION;

static {
JAVA_VERSION = System.getProperty("java.version");
final String[] versionStrings = JAVA_VERSION.split("\\.");

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we write like,

double version = Double.parseDouble(System.getProperty("java.specification.version"));
if(version > 1.8) {
//Do something
} else {
//Do something
}

Just curious, why? and why not? It eliminates the need of this Utility class.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is Double.parseDouble("1.8.0")?

Copy link
Contributor Author

@bender316 bender316 Aug 6, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like java.specification.version just returns 1.x or 11 (in cases of new versioning) and not the full version. I didn't know about this property. So IMO we could use this and get rid of the JavaVersion class.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, apologies @mohamedanees6, I didn't notice java.specification.version vs java.version. That does look better to me, especially since java.version seems to have an unreliable format: https://stackoverflow.com/a/5103166/1153071

Your call @bender316 :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will switch to the proposal above and remove the JavaVersion class.

int major = Integer.parseInt(versionStrings[0]);
// Java version prior to 10 used 1.x versioning
if (major == 1) {
major = Integer.parseInt(versionStrings[1]);
}
MAJOR_VERSION = major;
}

/**
* @return the full Java version (e.g. 1.8.0_211)
*/
public static String getJavaVersion() {
return JAVA_VERSION;
}

/**
* @return the major version of the java release (e.g. 8 or 11)
*/
public static int getMajorVersion() {
return MAJOR_VERSION;
}

}
2 changes: 2 additions & 0 deletions plugin-gradle/CHANGES.md
Expand Up @@ -2,6 +2,8 @@

### Version 3.25.0-SNAPSHOT - TBD ([javadoc](https://diffplug.github.io/spotless/javadoc/snapshot/), [snapshot](https://oss.sonatype.org/content/repositories/snapshots/com/diffplug/spotless/spotless-plugin-gradle/))

* Fixes class loading issue with Java 9+ ([#426](https://github.com/diffplug/spotless/pull/426)).

### Version 3.24.0 - July 29th 2019 ([javadoc](https://diffplug.github.io/spotless/javadoc/spotless-plugin-gradle/3.24.0/), [jcenter](https://bintray.com/diffplug/opensource/spotless-plugin-gradle/3.24.0))

* Updated default eclipse-wtp from 4.8.0 to 4.12.0 ([#423](https://github.com/diffplug/spotless/pull/423)).
Expand Down
2 changes: 2 additions & 0 deletions plugin-maven/CHANGES.md
Expand Up @@ -2,6 +2,8 @@

### Version 1.25.0-SNAPSHOT - TBD ([javadoc](https://diffplug.github.io/spotless/javadoc/spotless-maven-plugin/snapshot/), [snapshot](https://oss.sonatype.org/content/repositories/snapshots/com/diffplug/spotless/spotless-maven-plugin/))

* Fixes class loading issue with Java 9+ ([#426](https://github.com/diffplug/spotless/pull/426)).

### Version 1.24.0 - July 29th 2019 ([javadoc](https://diffplug.github.io/spotless/javadoc/spotless-maven-plugin/1.24.0/), [jcenter](https://bintray.com/diffplug/opensource/spotless-maven-plugin/1.24.0))

* Updated default eclipse-wtp from 4.8.0 to 4.12.0 ([#423](https://github.com/diffplug/spotless/pull/423)).
Expand Down