All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.jetty.osgi.LibExtClassLoaderHelper Maven / Gradle / Ivy

There is a newer version: 12.1.0.alpha0
Show newest version
//
// ========================================================================
// Copyright (c) 1995 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

package org.eclipse.jetty.osgi;

import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

import org.eclipse.jetty.util.FileID;

/**
 * LibExtClassLoaderHelper
 * 

* Helper to create a URL class-loader with the jars inside * ${jetty.home}/lib/ext and ${jetty.home}/resources. In an ideal world, every * library is an OSGi bundle that does loads nicely. To support standard jars or * bundles that cannot be loaded in the current OSGi environment, we support * inserting the jars in the usual jetty/lib/ext folders in the proper classpath * for the webapps. *

* The drawback is that those jars will not be available in the OSGi * classloader. *

* Alternatives to placing jars in lib/ext: *

    *
  1. Bundle the jars in an osgi bundle. Have the webapp(s) that need these jars * depend on that bundle.
  2. *
  3. Bundle those jars in an osgi bundle-fragment that targets the * jetty-bootstrap bundle
  4. *
  5. Use equinox Buddy-Policy: register a buddy of the jetty bootstrapper * bundle. (Note: it will work only on equinox)
  6. *
*/ public class LibExtClassLoaderHelper { /** * IFilesInJettyHomeResourcesProcessor * * Interface for callback impls */ public interface IFilesInJettyHomeResourcesProcessor { void processFilesInResourcesFolder(File jettyHome, Map filesInResourcesFolder); } public static final Set registeredFilesInJettyHomeResourcesProcessors = new HashSet<>(); /** * @param jettyHome the jetty home * @param parentClassLoader the parent classloader * @return a url classloader with the jars of resources, lib/ext and the * jars passed in the other argument. The parent classloader usually * is the JettyBootStrapper (an osgi classloader. * @throws MalformedURLException if the jetty home reference is invalid */ public static ClassLoader createLibEtcClassLoader(File jettyHome, ClassLoader parentClassLoader) throws MalformedURLException { if (jettyHome == null) { return parentClassLoader; } ArrayList urls = new ArrayList<>(); File jettyResources = new File(jettyHome, "resources"); if (jettyResources.exists()) { // make sure it contains something else than README: Map jettyResFiles = new HashMap<>(); for (File f : jettyResources.listFiles()) { jettyResFiles.put(f.getName(), f); if (f.getName().toLowerCase(Locale.ENGLISH).startsWith("readme")) { continue; } else { if (urls.isEmpty()) { urls.add(jettyResources.toURI().toURL()); } } } processFilesInResourcesFolder(jettyHome, jettyResFiles); } File libExt = new File(jettyHome, "lib/ext"); if (libExt.exists()) { for (File f : libExt.listFiles()) { if (FileID.isJavaArchive(f.getName())) { // cheap to tolerate folders so let's do it. URL url = f.toURI().toURL(); if (f.isFile()) { // is this necessary anyways? url = new URL("jar:" + url.toString() + "!/"); } urls.add(url); } } } return new URLClassLoader(urls.toArray(new URL[urls.size()]), parentClassLoader); } /** * @param jarsContainerOrJars the jars via file references * @param otherJarsOrFolder more jars via url references * @param parentClassLoader the parent classloader * @return a url classloader with the jars of resources, lib/ext and the * jars passed in the other argument. The parent classloader usually * is the JettyBootStrapper (an osgi classloader). If there was no * extra jars to insert, then just return the parentClassLoader. * @throws MalformedURLException if there is a bad jar file reference */ public static ClassLoader createLibExtClassLoader(List jarsContainerOrJars, List otherJarsOrFolder, ClassLoader parentClassLoader) throws MalformedURLException { if (jarsContainerOrJars == null && otherJarsOrFolder == null) { return parentClassLoader; } List urls = new ArrayList<>(); if (otherJarsOrFolder != null) { urls.addAll(otherJarsOrFolder); } if (jarsContainerOrJars != null) { for (File libExt : jarsContainerOrJars) { if (libExt.isDirectory()) { for (File f : libExt.listFiles()) { if (FileID.isJavaArchive(f.getName())) { // cheap to tolerate folders so let's do it. URL url = f.toURI().toURL(); if (f.isFile()) { // is this necessary anyways? url = new URL("jar:" + url.toString() + "!/"); } urls.add(url); } } } } } return new URLClassLoader(urls.toArray(new URL[urls.size()]), parentClassLoader); } /** * When we find files typically used for central logging configuration we do * what it takes in this method to do what the user expects. Without * depending too much directly on a particular logging framework. *

* We can afford to do some implementation specific code for a logging * framework only in a fragment. *

* Trying to configure log4j and logback in here. *

* We recommend that slf4j jars are all placed in the osgi framework. And a * single implementation if possible packaged as an osgi bundle is there. * * @param jettyHome the jetty home reference * @param childrenFiles the map of child files */ protected static void processFilesInResourcesFolder(File jettyHome, Map childrenFiles) { for (IFilesInJettyHomeResourcesProcessor processor : registeredFilesInJettyHomeResourcesProcessors) { processor.processFilesInResourcesFolder(jettyHome, childrenFiles); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy