Merged in bugfix/openapi_errors (pull request #417)

prevent using same classloader multiple times
This commit is contained in:
Sebastian Sdorra
2020-03-04 08:31:08 +00:00
11 changed files with 140 additions and 108 deletions

View File

@@ -185,7 +185,8 @@ public class BranchRootResource {
description = "create success",
headers = @Header(
name = "Location",
description = "uri to the created branch"
description = "uri to the created branch",
schema = @Schema(type = "string")
)
)
@ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials")

View File

@@ -95,13 +95,14 @@ public class GroupCollectionResource {
@POST
@Path("")
@Consumes(VndMediaType.GROUP)
@Operation(summary = "Create group", description = "Creates a new group.", tags = "Group")
@Operation(summary = "Create group", description = "Creates a new group.", tags = "Group", operationId = "group_create")
@ApiResponse(
responseCode = "201",
description = "create success",
headers = @Header(
name = "Location",
description = "uri to the created group"
description = "uri to the created group",
schema = @Schema(type = "string")
)
)
@ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials")

View File

@@ -109,7 +109,8 @@ public class RepositoryCollectionResource {
description = "create success",
headers = @Header(
name = "Location",
description = "uri to the created repository"
description = "uri to the created repository",
schema = @Schema(type = "string")
)
)
@ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials")

View File

@@ -9,9 +9,9 @@ import lombok.extern.slf4j.Slf4j;
import sonia.scm.AlreadyExistsException;
import sonia.scm.NotFoundException;
import sonia.scm.repository.NamespaceAndName;
import sonia.scm.repository.RepositoryPermission;
import sonia.scm.repository.Repository;
import sonia.scm.repository.RepositoryManager;
import sonia.scm.repository.RepositoryPermission;
import sonia.scm.repository.RepositoryPermissions;
import sonia.scm.web.VndMediaType;
@@ -71,7 +71,11 @@ public class RepositoryPermissionRootResource {
@ApiResponse(
responseCode = "201",
description = "creates",
headers = @Header(name = "Location", description = "uri of the created permission")
headers = @Header(
name = "Location",
description = "uri of the created permission",
schema = @Schema(type = "string")
)
)
@ApiResponse(
responseCode = "404",

View File

@@ -96,7 +96,8 @@ public class RepositoryRoleCollectionResource {
description = "create success",
headers = @Header(
name = "Location",
description = "uri to the created repository role"
description = "uri to the created repository role",
schema = @Schema(type = "string")
)
)
@ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials")

View File

@@ -105,7 +105,8 @@ public class UserCollectionResource {
description = "create success",
headers = @Header(
name = "Location",
description = "uri to the created user"
description = "uri to the created user",
schema = @Schema(type = "string")
)
)
@ApiResponse(responseCode = "401", description = "not authenticated / invalid credentials")

View File

@@ -1,9 +1,9 @@
/**
* Copyright (c) 2010, Sebastian Sdorra All rights reserved.
*
* <p>
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* <p>
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer. 2. Redistributions in
* binary form must reproduce the above copyright notice, this list of
@@ -11,7 +11,7 @@
* materials provided with the distribution. 3. Neither the name of SCM-Manager;
* nor the names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* <p>
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -22,60 +22,59 @@
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* <p>
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.plugin;
//~--- non-JDK imports --------------------------------------------------------
import com.google.common.collect.Lists;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
//~--- JDK imports ------------------------------------------------------------
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.net.URL;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentMap;
//~--- JDK imports ------------------------------------------------------------
/**
* {@link ClassLoader} which is able to load classes and resources from all
* plugins.
*
* @author Sebastian Sdorra
*/
public final class UberClassLoader extends ClassLoader
{
public final class UberClassLoader extends ClassLoader {
/**
* Constructs ...
*
*
* @param parent
* @param plugins
*/
public UberClassLoader(ClassLoader parent, Iterable<InstalledPlugin> plugins)
{
super(parent);
this.plugins = plugins;
private final Set<ClassLoader> pluginClassLoaders;
private final ConcurrentMap<String, WeakReference<Class<?>>> cache = Maps.newConcurrentMap();
public UberClassLoader(ClassLoader parent, Iterable<InstalledPlugin> plugins) {
this(parent, collectClassLoaders(plugins));
}
//~--- methods --------------------------------------------------------------
private static Set<ClassLoader> collectClassLoaders(Iterable<InstalledPlugin> plugins) {
ImmutableSet.Builder<ClassLoader> classLoaders = ImmutableSet.builder();
plugins.forEach(plugin -> classLoaders.add(plugin.getClassLoader()));
return classLoaders.build();
}
@VisibleForTesting
UberClassLoader(ClassLoader parent, Set<ClassLoader> pluginClassLoaders) {
super(parent);
this.pluginClassLoaders = pluginClassLoaders;
}
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException
{
protected Class<?> findClass(String name) throws ClassNotFoundException {
Class<?> clazz = getFromCache(name);
if (clazz == null) {
@@ -87,8 +86,8 @@ public final class UberClassLoader extends ClassLoader
}
private Class<?> findClassInPlugins(String name) throws ClassNotFoundException {
for (InstalledPlugin plugin : plugins) {
Class<?> clazz = findClass(plugin.getClassLoader(), name);
for (ClassLoader pluginClassLoader : pluginClassLoaders) {
Class<?> clazz = findClass(pluginClassLoader, name);
if (clazz != null) {
return clazz;
}
@@ -106,27 +105,14 @@ public final class UberClassLoader extends ClassLoader
}
}
/**
* Method description
*
*
* @param name
*
* @return
*/
@Override
protected URL findResource(String name)
{
protected URL findResource(String name) {
URL url = null;
for (InstalledPlugin plugin : plugins)
{
ClassLoader cl = plugin.getClassLoader();
for (ClassLoader pluginClassLoader : pluginClassLoaders) {
url = pluginClassLoader.getResource(name);
url = cl.getResource(name);
if (url != null)
{
if (url != null) {
break;
}
}
@@ -134,52 +120,26 @@ public final class UberClassLoader extends ClassLoader
return url;
}
/**
* Method description
*
*
* @param name
*
* @return
*
* @throws IOException
*/
@Override
protected Enumeration<URL> findResources(String name) throws IOException
{
List<URL> urls = Lists.newArrayList();
@SuppressWarnings("squid:S2112")
protected Enumeration<URL> findResources(String name) throws IOException {
Set<URL> urls = new LinkedHashSet<>();
for (InstalledPlugin plugin : plugins)
{
ClassLoader cl = plugin.getClassLoader();
urls.addAll(Collections.list(cl.getResources(name)));
for (ClassLoader pluginClassLoader : pluginClassLoaders) {
urls.addAll(Collections.list(pluginClassLoader.getResources(name)));
}
return Collections.enumeration(urls);
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param name
*
* @return
*/
private Class<?> getFromCache(String name)
{
private Class<?> getFromCache(String name) {
Class<?> clazz = null;
WeakReference<Class<?>> ref = cache.get(name);
if (ref != null)
{
if (ref != null) {
clazz = ref.get();
if (clazz == null)
{
if (clazz == null) {
cache.remove(name);
}
}
@@ -187,12 +147,4 @@ public final class UberClassLoader extends ClassLoader
return clazz;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private final ConcurrentMap<String, WeakReference<Class<?>>> cache =
Maps.newConcurrentMap();
/** Field description */
private final Iterable<InstalledPlugin> plugins;
}