Skip to content

Commit

Permalink
Avoid casting classloader to URLLoader in ResourceModelEncoder to be …
Browse files Browse the repository at this point in the history
…compatible with Java 11 (#822)

* Avoid casting classloader to URLLoader in ResourceModelEncoder to be compatible with Java 11
  • Loading branch information
junchuanwang authored Aug 22, 2022
1 parent ce2b743 commit e5e24a5
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 35 deletions.
7 changes: 6 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ and what APIs have changed, if applicable.

## [Unreleased]

## [29.37.14] - 2022-08-19
- Avoid casting classloader to URLLoader in ResourceModelEncoder and use ClassGraph to search for restspec file


## [29.37.13] - 2022-08-15
- Fix d2-test-api dependencies

Expand Down Expand Up @@ -5303,7 +5307,8 @@ patch operations can re-use these classes for generating patch messages.

## [0.14.1]

[Unreleased]: https://github.com/linkedin/rest.li/compare/v29.37.13...master
[Unreleased]: https://github.com/linkedin/rest.li/compare/v29.37.14...master
[29.37.14]: https://github.com/linkedin/rest.li/compare/v29.37.13...v29.37.14
[29.37.13]: https://github.com/linkedin/rest.li/compare/v29.37.12...v29.37.13
[29.37.12]: https://github.com/linkedin/rest.li/compare/v29.37.11...v29.37.12
[29.37.11]: https://github.com/linkedin/rest.li/compare/v29.37.10...v29.37.11
Expand Down
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ project.ext.externalDependency = [

'jsr305': 'com.google.code.findbugs:jsr305:3.0.0',
"avroSpotBugsPlugin": "com.linkedin.avroutil1:spotbugs-plugin:0.2.56",
"classgraph": "io.github.classgraph:classgraph:4.8.149",
];

if (!project.ext.isDefaultEnvironment)
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version=29.37.13
version=29.37.14
group=com.linkedin.pegasus
org.gradle.configureondemand=true
org.gradle.parallel=true
Expand Down
1 change: 1 addition & 0 deletions restli-server/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ dependencies {
compile externalDependency.parseq
compile externalDependency.servletApi
compile externalDependency.antlrRuntime
compile externalDependency.classgraph

antlr externalDependency.antlr

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,11 +76,12 @@
import com.linkedin.restli.server.annotations.BatchFinder;
import com.linkedin.restli.server.errors.ServiceError;
import com.linkedin.restli.server.errors.ParametersServiceError;
import java.io.File;
import io.github.classgraph.ClassGraph;
import io.github.classgraph.Resource;
import io.github.classgraph.ResourceList;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
Expand All @@ -96,6 +97,7 @@
import java.util.jar.JarInputStream;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;


Expand All @@ -117,9 +119,9 @@ public class ResourceModelEncoder

private final DataCodec codec = new JacksonDataCodec();

// Used to cache the mapping between restspec file and
// the class loader that can get the resource
private Map<String, ClassLoader> _restSpecToClassLoaderMap = null;
// Used to cache the mapping between restspec file name and
// the Resource object
private Map<String, Resource> _restSpecPathToResourceMap = null;

/**
* Provides documentation strings from a JVM language to be incorporated into ResourceModels.
Expand Down Expand Up @@ -339,47 +341,46 @@ public ResourceSchema loadOrBuildResourceSchema(final ResourceModel resourceMode
}
}

private InputStream getResourceStreamBySearchingRestSpec(String resourceName, ClassLoader... classLoaders)
{
private InputStream getResourceStreamBySearchingRestSpec(String resourceName, ClassLoader... classLoaders) {
if (!resourceName.endsWith(REST_SPEC_JSON_SUFFIX))
{
return null;
}
if (_restSpecToClassLoaderMap == null)
if (_restSpecPathToResourceMap == null)
{
_restSpecToClassLoaderMap = new HashMap<>();
for(ClassLoader classLoader: classLoaders)
_restSpecPathToResourceMap = new HashMap<>();
try
{
URL[] urls = ((URLClassLoader) classLoader).getURLs();
for (URL url : urls)
{
if (!url.toString().toLowerCase().endsWith("jar"))
{
continue;
}
try
{
JarInputStream jarIn = new JarInputStream(url.openStream());
for (JarEntry e = jarIn.getNextJarEntry(); e != null; e = jarIn.getNextJarEntry()) {
if (!e.isDirectory() && e.getName().endsWith(REST_SPEC_JSON_SUFFIX))
{
_restSpecToClassLoaderMap.put(e.getName(), classLoader);
}
ResourceList resourceList = new ClassGraph().overrideClassLoaders(classLoaders)
.scan().getResourcesWithExtension(REST_SPEC_JSON_SUFFIX);
resourceList.forEach( resource -> {
_restSpecPathToResourceMap.put(FilenameUtils.getName(resource.getPath()),
resource);
}
}
catch (IOException e)
{
// Will not add the entry
}
}
);
}
catch (Exception e)
{
// don't throw exception
}
}

for (Map.Entry<String, ClassLoader> entry : _restSpecToClassLoaderMap.entrySet())
for (Map.Entry<String, Resource> entry : _restSpecPathToResourceMap.entrySet())
{
// looking for file path suffix matching
// e.g.
// for "mypackage.myresource.restspec.json"
// looking for "myapiname-mypackage.myresource.restspec.json"
if (entry.getKey().endsWith("-" + resourceName))
{
return entry.getValue().getResourceAsStream(entry.getKey());
try
{
return entry.getValue().open();
}
catch (Exception e)
{
return null;
}
}
}
return null;
Expand Down

0 comments on commit e5e24a5

Please sign in to comment.