nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/DynamicLinkerFactory.java
changeset 34456 84eaea8d0574
parent 34096 5ac6287ec71a
parent 34455 cc9f05d3caf0
child 34457 81a65a2faef3
--- a/nashorn/src/jdk.scripting.nashorn/share/classes/jdk/internal/dynalink/DynamicLinkerFactory.java	Wed Jul 05 21:04:26 2017 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,527 +0,0 @@
-/*
- * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-/*
- * This file is available under and governed by the GNU General Public
- * License version 2 only, as published by the Free Software Foundation.
- * However, the following notice accompanied the original version of this
- * file, and Oracle licenses the original version of this file under the BSD
- * license:
- */
-/*
-   Copyright 2009-2013 Attila Szegedi
-
-   Licensed under both the Apache License, Version 2.0 (the "Apache License")
-   and the BSD License (the "BSD License"), with licensee being free to
-   choose either of the two at their discretion.
-
-   You may not use this file except in compliance with either the Apache
-   License or the BSD License.
-
-   If you choose to use this file in compliance with the Apache License, the
-   following notice applies to you:
-
-       You may obtain a copy of the Apache 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.
-
-   If you choose to use this file in compliance with the BSD License, the
-   following notice applies to you:
-
-       Redistribution and use in source and binary forms, with or without
-       modification, are permitted provided that the following conditions are
-       met:
-       * Redistributions of source code must retain the above copyright
-         notice, this list of conditions and the following disclaimer.
-       * Redistributions in binary form must reproduce the above copyright
-         notice, this list of conditions and the following disclaimer in the
-         documentation and/or other materials provided with the distribution.
-       * Neither the name of the copyright holder nor the names of
-         contributors may be used to endorse or promote products derived from
-         this software without specific prior written permission.
-
-       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 ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
-       BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-       CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
-       BUSINESS INTERRUPTION) HOWEVER 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.
-*/
-
-package jdk.internal.dynalink;
-
-import java.lang.invoke.MethodHandle;
-import java.lang.invoke.MethodType;
-import java.lang.invoke.MutableCallSite;
-import java.security.AccessControlContext;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Objects;
-import java.util.ServiceConfigurationError;
-import java.util.ServiceLoader;
-import java.util.Set;
-import java.util.function.Supplier;
-import jdk.internal.dynalink.beans.BeansLinker;
-import jdk.internal.dynalink.internal.AccessControlContextFactory;
-import jdk.internal.dynalink.linker.GuardedInvocation;
-import jdk.internal.dynalink.linker.GuardedInvocationTransformer;
-import jdk.internal.dynalink.linker.GuardingDynamicLinker;
-import jdk.internal.dynalink.linker.GuardingDynamicLinkerExporter;
-import jdk.internal.dynalink.linker.GuardingTypeConverterFactory;
-import jdk.internal.dynalink.linker.LinkRequest;
-import jdk.internal.dynalink.linker.LinkerServices;
-import jdk.internal.dynalink.linker.MethodHandleTransformer;
-import jdk.internal.dynalink.linker.MethodTypeConversionStrategy;
-import jdk.internal.dynalink.linker.support.CompositeGuardingDynamicLinker;
-import jdk.internal.dynalink.linker.support.CompositeTypeBasedGuardingDynamicLinker;
-import jdk.internal.dynalink.linker.support.DefaultInternalObjectFilter;
-import jdk.internal.dynalink.linker.support.TypeUtilities;
-
-/**
- * A factory class for creating {@link DynamicLinker} objects. Dynamic linkers
- * are the central objects in Dynalink; these are composed of several
- * {@link GuardingDynamicLinker} objects and coordinate linking of call sites
- * with them. The usual dynamic linker is a linker
- * composed of all {@link GuardingDynamicLinker} objects explicitly pre-created
- * by the user of the factory and configured with
- * {@link #setPrioritizedLinkers(List)}, as well as any
- * {@link #setClassLoader(ClassLoader) automatically discovered} ones, and
- * finally the ones configured with {@link #setFallbackLinkers(List)}; this last
- * category usually includes {@link BeansLinker}.
- */
-public final class DynamicLinkerFactory {
-    private static final AccessControlContext GET_CLASS_LOADER_CONTEXT =
-            AccessControlContextFactory.createAccessControlContext("getClassLoader");
-
-    /**
-     * Default value for {@link #setUnstableRelinkThreshold(int) unstable relink
-     * threshold}.
-     */
-    private static final int DEFAULT_UNSTABLE_RELINK_THRESHOLD = 8;
-
-    private boolean classLoaderExplicitlySet = false;
-    private ClassLoader classLoader;
-
-    private List<? extends GuardingDynamicLinker> prioritizedLinkers;
-    private List<? extends GuardingDynamicLinker> fallbackLinkers;
-    private boolean syncOnRelink = false;
-    private int unstableRelinkThreshold = DEFAULT_UNSTABLE_RELINK_THRESHOLD;
-    private GuardedInvocationTransformer prelinkTransformer;
-    private MethodTypeConversionStrategy autoConversionStrategy;
-    private MethodHandleTransformer internalObjectsFilter;
-
-    private List<ServiceConfigurationError> autoLoadingErrors = Collections.emptyList();
-
-    /**
-     * Creates a new dynamic linker factory with default configuration. Upon
-     * creation, the factory can be configured using various {@code setXxx()}
-     * methods and used to create one or more dynamic linkers according to its
-     * current configuration using {@link #createLinker()}.
-     */
-    public DynamicLinkerFactory() {
-    }
-
-    /**
-     * Sets the class loader for automatic discovery of available guarding
-     * dynamic linkers. {@link GuardingDynamicLinkerExporter} implementations
-     * available through this class loader will be automatically instantiated
-     * using the {@link ServiceLoader} mechanism and the linkers they provide
-     * will be incorporated into {@code DynamicLinker}s that this factory
-     * creates. This allows for cross-language interoperability where call sites
-     * belonging to this language runtime can be linked by linkers from these
-     * automatically discovered runtimes if their native objects are passed to
-     * this runtime. If class loader is not set explicitly by invoking this
-     * method, then the thread context class loader of the thread invoking
-     * {@link #createLinker()} will be used. If this method is invoked
-     * explicitly with null then {@link ServiceLoader#loadInstalled(Class)} will
-     * be used to load the linkers.
-     *
-     * @param classLoader the class loader used for the automatic discovery of
-     * available linkers.
-     */
-    public void setClassLoader(final ClassLoader classLoader) {
-        this.classLoader = classLoader;
-        classLoaderExplicitlySet = true;
-    }
-
-    /**
-     * Sets the prioritized guarding dynamic linkers. Language runtimes using
-     * Dynalink will usually have at least one linker for their own language.
-     * These linkers will be consulted first by the resulting dynamic linker
-     * when it is linking call sites, before any autodiscovered and fallback
-     * linkers. If the factory also autodiscovers a linker class matching one
-     * of the prioritized linkers, the autodiscovered class will be ignored and
-     * the explicit prioritized instance will be used.
-     *
-     * @param prioritizedLinkers the list of prioritized linkers. Can be null.
-     * @throws NullPointerException if any of the list elements are null.
-     */
-    public void setPrioritizedLinkers(final List<? extends GuardingDynamicLinker> prioritizedLinkers) {
-        this.prioritizedLinkers = copyListRequireNonNullElements(prioritizedLinkers);
-    }
-
-    /**
-     * Sets the prioritized guarding dynamic linkers. Identical to calling
-     * {@link #setPrioritizedLinkers(List)} with
-     * {@code Arrays.asList(prioritizedLinkers)}.
-     *
-     * @param prioritizedLinkers an array of prioritized linkers. Can be null.
-     * @throws NullPointerException if any of the array elements are null.
-     */
-    public void setPrioritizedLinkers(final GuardingDynamicLinker... prioritizedLinkers) {
-        setPrioritizedLinkers(prioritizedLinkers == null ? null : Arrays.asList(prioritizedLinkers));
-    }
-
-    /**
-     * Sets a single prioritized linker. Identical to calling
-     * {@link #setPrioritizedLinkers(List)} with a single-element list.
-     *
-     * @param prioritizedLinker the single prioritized linker. Must not be null.
-     * @throws NullPointerException if null is passed.
-     */
-    public void setPrioritizedLinker(final GuardingDynamicLinker prioritizedLinker) {
-        this.prioritizedLinkers = Collections.singletonList(Objects.requireNonNull(prioritizedLinker));
-    }
-
-    /**
-     * Sets the fallback guarding dynamic linkers. These linkers will be
-     * consulted last by the resulting dynamic linker when it is linking call
-     * sites, after any autodiscovered and prioritized linkers. If the factory
-     * also autodiscovers a linker class matching one of the fallback linkers,
-     * the autodiscovered class will be ignored and the explicit fallback
-     * instance will be used.
-     *
-     * @param fallbackLinkers the list of fallback linkers. Can be empty to
-     * indicate the caller wishes to set no fallback linkers. Note that if this
-     * method is not invoked explicitly or is passed null, then the factory
-     * will create an instance of {@link BeansLinker} to serve as the default
-     * fallback linker.
-     * @throws NullPointerException if any of the list elements are null.
-     */
-    public void setFallbackLinkers(final List<? extends GuardingDynamicLinker> fallbackLinkers) {
-        this.fallbackLinkers = copyListRequireNonNullElements(fallbackLinkers);
-    }
-
-    /**
-     * Sets the fallback guarding dynamic linkers. Identical to calling
-     * {@link #setFallbackLinkers(List)} with
-     * {@code Arrays.asList(fallbackLinkers)}.
-     *
-     * @param fallbackLinkers an array of fallback linkers. Can be empty to
-     * indicate the caller wishes to set no fallback linkers. Note that if this
-     * method is not invoked explicitly or is passed null, then the factory
-     * will create an instance of {@link BeansLinker} to serve as the default
-     * fallback linker.
-     * @throws NullPointerException if any of the array elements are null.
-     */
-    public void setFallbackLinkers(final GuardingDynamicLinker... fallbackLinkers) {
-        setFallbackLinkers(fallbackLinkers == null ? null : Arrays.asList(fallbackLinkers));
-    }
-
-    /**
-     * Sets whether the dynamic linker created by this factory will invoke
-     * {@link MutableCallSite#syncAll(MutableCallSite[])} after a call site is
-     * relinked. Defaults to false. You probably want to set it to true if your
-     * runtime supports multithreaded execution of dynamically linked code.
-     * @param syncOnRelink true for invoking sync on relink, false otherwise.
-     */
-    public void setSyncOnRelink(final boolean syncOnRelink) {
-        this.syncOnRelink = syncOnRelink;
-    }
-
-    /**
-     * Sets the unstable relink threshold; the number of times a call site is
-     * relinked after which it will be considered unstable, and subsequent link
-     * requests for it will indicate this. Defaults to 8 when not set explicitly.
-     * @param unstableRelinkThreshold the new threshold. Must not be less than
-     * zero. The value of zero means that call sites will never be considered
-     * unstable.
-     * @see LinkRequest#isCallSiteUnstable()
-     */
-    public void setUnstableRelinkThreshold(final int unstableRelinkThreshold) {
-        if(unstableRelinkThreshold < 0) {
-            throw new IllegalArgumentException("unstableRelinkThreshold < 0");
-        }
-        this.unstableRelinkThreshold = unstableRelinkThreshold;
-    }
-
-    /**
-     * Set the pre-link transformer. This is a
-     * {@link GuardedInvocationTransformer} that will get the final chance to
-     * modify the guarded invocation after it has been created by a component
-     * linker and before the dynamic linker links it into the call site. It is
-     * normally used to adapt the return value type of the invocation to the
-     * type of the call site. When not set explicitly, a default pre-link
-     * transformer will be used that simply calls
-     * {@link GuardedInvocation#asType(LinkerServices, MethodType)}. Customized
-     * pre-link transformers are rarely needed; they are mostly used as a
-     * building block for implementing advanced techniques such as code
-     * deoptimization strategies.
-     * @param prelinkTransformer the pre-link transformer for the dynamic
-     * linker. Can be null to have the factory use the default transformer.
-     */
-    public void setPrelinkTransformer(final GuardedInvocationTransformer prelinkTransformer) {
-        this.prelinkTransformer = prelinkTransformer;
-    }
-
-    /**
-     * Sets an object representing the conversion strategy for automatic type
-     * conversions. After
-     * {@link LinkerServices#asType(MethodHandle, MethodType)} has applied all
-     * custom conversions to a method handle, it still needs to effect
-     * {@link TypeUtilities#isMethodInvocationConvertible(Class, Class) method
-     * invocation conversions} that can usually be automatically applied as per
-     * {@link MethodHandle#asType(MethodType)}. However, sometimes language
-     * runtimes will want to customize even those conversions for their own call
-     * sites. A typical example is allowing unboxing of null return values,
-     * which is by default prohibited by ordinary
-     * {@code MethodHandles.asType()}. In this case, a language runtime can
-     * install its own custom automatic conversion strategy, that can deal with
-     * null values. Note that when the strategy's
-     * {@link MethodTypeConversionStrategy#asType(MethodHandle, MethodType)}
-     * is invoked, the custom language conversions will already have been
-     * applied to the method handle, so by design the difference between the
-     * handle's current method type and the desired final type will always only
-     * be ones that can be subjected to method invocation conversions. The
-     * strategy also doesn't need to invoke a final
-     * {@code MethodHandle.asType()} as that will be done internally as the
-     * final step.
-     * @param autoConversionStrategy the strategy for applying method invocation
-     * conversions for the linker created by this factory. Can be null for no
-     * custom strategy.
-     */
-    public void setAutoConversionStrategy(final MethodTypeConversionStrategy autoConversionStrategy) {
-        this.autoConversionStrategy = autoConversionStrategy;
-    }
-
-    /**
-     * Sets a method handle transformer that is supposed to act as the
-     * implementation of
-     * {@link LinkerServices#filterInternalObjects(MethodHandle)} for linker
-     * services of dynamic linkers created by this factory. Some language
-     * runtimes can have internal objects that should not escape their scope.
-     * They can add a transformer here that will modify the method handle so
-     * that any parameters that can receive potentially internal language
-     * runtime objects will have a filter added on them to prevent them from
-     * escaping, potentially by wrapping them. The transformer can also
-     * potentially add an unwrapping filter to the return value.
-     * {@link DefaultInternalObjectFilter} is provided as a convenience class
-     * for easily creating such filtering transformers.
-     * @param internalObjectsFilter a method handle transformer filtering out
-     * internal objects, or null.
-     */
-    public void setInternalObjectsFilter(final MethodHandleTransformer internalObjectsFilter) {
-        this.internalObjectsFilter = internalObjectsFilter;
-    }
-
-    /**
-     * Creates a new dynamic linker based on the current configuration. This
-     * method can be invoked more than once to create multiple dynamic linkers.
-     * Automatically discovered linkers are newly instantiated on every
-     * invocation of this method. It is allowed to change the factory's
-     * configuration between invocations. The method is not thread safe. After
-     * invocation, callers can invoke {@link #getAutoLoadingErrors()} to
-     * retrieve a list of {@link ServiceConfigurationError}s that occurred while
-     * trying to load automatically discovered linkers. These are never thrown
-     * from the call to this method as it makes every effort to recover from
-     * them and ignore the failing linkers.
-     * @return the new dynamic Linker
-     */
-    public DynamicLinker createLinker() {
-        // Treat nulls appropriately
-        if(prioritizedLinkers == null) {
-            prioritizedLinkers = Collections.emptyList();
-        }
-        if(fallbackLinkers == null) {
-            fallbackLinkers = Collections.singletonList(new BeansLinker());
-        }
-
-        // Gather classes of all precreated (prioritized and fallback) linkers.
-        // We'll filter out any discovered linkers of the same class.
-        final Set<Class<? extends GuardingDynamicLinker>> knownLinkerClasses =
-                new HashSet<>();
-        addClasses(knownLinkerClasses, prioritizedLinkers);
-        addClasses(knownLinkerClasses, fallbackLinkers);
-
-        final List<GuardingDynamicLinker> discovered = discoverAutoLoadLinkers();
-
-        // Now, concatenate ...
-        final List<GuardingDynamicLinker> linkers =
-                new ArrayList<>(prioritizedLinkers.size() + discovered.size()
-                        + fallbackLinkers.size());
-        // ... prioritized linkers, ...
-        linkers.addAll(prioritizedLinkers);
-        // ... filtered discovered linkers, ...
-        for(final GuardingDynamicLinker linker: discovered) {
-            if(!knownLinkerClasses.contains(linker.getClass())) {
-                linkers.add(linker);
-            }
-        }
-        // ... and finally fallback linkers.
-        linkers.addAll(fallbackLinkers);
-        final List<GuardingDynamicLinker> optimized = CompositeTypeBasedGuardingDynamicLinker.optimize(linkers);
-        final GuardingDynamicLinker composite;
-        switch(linkers.size()) {
-            case 0: {
-                composite = (r, s) -> null; // linker that can't link anything
-                break;
-            }
-            case 1: {
-                composite = optimized.get(0);
-                break;
-            }
-            default: {
-                composite = new CompositeGuardingDynamicLinker(optimized);
-                break;
-            }
-        }
-
-        final List<GuardingTypeConverterFactory> typeConverters = new LinkedList<>();
-        for(final GuardingDynamicLinker linker: linkers) {
-            if(linker instanceof GuardingTypeConverterFactory) {
-                typeConverters.add((GuardingTypeConverterFactory)linker);
-            }
-        }
-
-        if(prelinkTransformer == null) {
-            prelinkTransformer = (inv, request, linkerServices) -> inv.asType(linkerServices, request.getCallSiteDescriptor().getMethodType());
-        }
-
-        return new DynamicLinker(new LinkerServicesImpl(new TypeConverterFactory(typeConverters,
-                autoConversionStrategy), composite, internalObjectsFilter), prelinkTransformer,
-                syncOnRelink, unstableRelinkThreshold);
-    }
-
-    /**
-     * Returns a list of {@link ServiceConfigurationError}s that were
-     * encountered while loading automatically discovered linkers during the
-     * last invocation of {@link #createLinker()}. They can be any non-Dynalink
-     * specific service configuration issues, as well as some Dynalink-specific
-     * errors when an exporter that the factory tried to automatically load:
-     * <ul>
-     * <li>did not have the runtime permission named
-     * {@link GuardingDynamicLinkerExporter#AUTOLOAD_PERMISSION_NAME} in a
-     * system with a security manager, or</li>
-     * <li>returned null from {@link GuardingDynamicLinkerExporter#get()}, or</li>
-     * <li>the list returned from {@link GuardingDynamicLinkerExporter#get()}
-     * had a null element.</li>
-     * </ul>
-     * @return an immutable list of encountered
-     * {@link ServiceConfigurationError}s. Can be empty.
-     */
-    public List<ServiceConfigurationError> getAutoLoadingErrors() {
-        return Collections.unmodifiableList(autoLoadingErrors);
-    }
-
-    private List<GuardingDynamicLinker> discoverAutoLoadLinkers() {
-        autoLoadingErrors = new LinkedList<>();
-        final ClassLoader effectiveClassLoader = classLoaderExplicitlySet ? classLoader : getThreadContextClassLoader();
-        final List<GuardingDynamicLinker> discovered = new LinkedList<>();
-        try {
-            final ServiceLoader<GuardingDynamicLinkerExporter> linkerLoader =
-                    AccessController.doPrivileged((PrivilegedAction<ServiceLoader<GuardingDynamicLinkerExporter>>)()-> {
-                        if (effectiveClassLoader == null) {
-                            return ServiceLoader.loadInstalled(GuardingDynamicLinkerExporter.class);
-                        }
-                        return ServiceLoader.load(GuardingDynamicLinkerExporter.class, effectiveClassLoader);
-                    });
-
-            for(final Iterator<GuardingDynamicLinkerExporter> it = linkerLoader.iterator(); it.hasNext();) {
-                try {
-                    final GuardingDynamicLinkerExporter autoLoader = it.next();
-                    try {
-                        discovered.addAll(requireNonNullElements(
-                                Objects.requireNonNull(autoLoader.get(),
-                                        ()->(autoLoader.getClass().getName() + " returned null from get()")),
-                                ()->(autoLoader.getClass().getName() + " returned a list with at least one null element")));
-                    } catch (final ServiceConfigurationError|VirtualMachineError e) {
-                        // Don't wrap a SCE in another SCE. Also, don't ignore
-                        // any VME (e.g. StackOverflowError or OutOfMemoryError).
-                        throw e;
-                    } catch (final Throwable t) {
-                        throw new ServiceConfigurationError(t.getMessage(), t);
-                    }
-                } catch (final ServiceConfigurationError e) {
-                    // Catch SCE with an individual exporter, carry on with it.hasNext().
-                    autoLoadingErrors.add(e);
-                }
-            }
-        } catch (final ServiceConfigurationError e) {
-            // Catch a top-level SCE; one either in ServiceLoader.load(),
-            // ServiceLoader.iterator(), or Iterator.hasNext().
-            autoLoadingErrors.add(e);
-        }
-        return discovered;
-    }
-
-    private static ClassLoader getThreadContextClassLoader() {
-        return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() {
-            @Override
-            public ClassLoader run() {
-                return Thread.currentThread().getContextClassLoader();
-            }
-        }, GET_CLASS_LOADER_CONTEXT);
-    }
-
-    private static void addClasses(final Set<Class<? extends GuardingDynamicLinker>> knownLinkerClasses,
-            final List<? extends GuardingDynamicLinker> linkers) {
-        for(final GuardingDynamicLinker linker: linkers) {
-            knownLinkerClasses.add(linker.getClass());
-        }
-    }
-
-    private static <T> List<T> copyListRequireNonNullElements(final List<T> list) {
-        if (list == null) {
-            return null;
-        }
-        return new ArrayList<>(requireNonNullElements(list, ()->"List has at least one null element"));
-    }
-
-    private static <T> List<T> requireNonNullElements(final List<T> list, final Supplier<String> msgSupplier) {
-        for(final T t: list) {
-            Objects.requireNonNull(t, msgSupplier);
-        }
-        return list;
-    }
-
-}