Changeset 5394


Ignore:
Timestamp:
Aug 25, 2010, 2:48:18 PM (13 years ago)
Author:
Nicklas Nordborg
Message:

Fixes #1500: JarClassLoader? should define packages

Location:
trunk/src
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/core/net/sf/basedb/util/JarClassLoader.java

    r5384 r5394  
    3434import java.util.jar.Manifest;
    3535import java.util.jar.Attributes;
     36import java.util.jar.Attributes.Name;
    3637import java.io.File;
    3738import java.io.InputStream;
     
    193194    in the manifest file.
    194195  */
    195   private final List<JarInfo> jarFiles;
     196  private final Map<File, JarInfo> jarFiles;
    196197 
    197198  /**
     
    226227    this.delegateFirst = false;
    227228    classPath = new HashMap<String, List<File>>();
    228     jarFiles = new ArrayList<JarInfo>();
     229    jarFiles = new HashMap<File, JarInfo>();
    229230    loadJarFile(mainJarFile, true);
    230231  }
     
    244245      throw new ClassNotFoundException(name);
    245246    }
    246     byte[] b = loadClassData(files.get(0), name);
    247     return defineClass(name, b, 0, b.length);
     247    File file = files.get(0);
     248    byte[] b = loadClassData(file, name);
     249    int i = name.lastIndexOf('.');
     250    if (i > 0)
     251    {
     252      String packageName = name.substring(0, i);
     253      Package pkg = getPackage(packageName);
     254      if (pkg == null)
     255      {
     256        JarInfo info = jarFiles.get(file);
     257        Manifest mf = info != null ? info.manifest : null;
     258        pkg = definePackage(packageName, mf);
     259      }
     260    }
     261    Class<?> clazz = defineClass(name, b, 0, b.length);
     262    return clazz;
    248263  }
    249264 
     
    435450    if (checkSecondary)
    436451    {
    437       for (JarInfo info : jarFiles)
     452      for (JarInfo info : jarFiles.values())
    438453      {
    439454        File jarFile = info.jarFile;
     
    476491  {
    477492    log.debug("loadJarFile: file=" + file);
    478     jarFiles.add(new JarInfo(file));
     493    JarInfo info = new JarInfo(file);
     494    jarFiles.put(file, info);
    479495    if (!file.exists() || !file.isFile())
    480496    {
     
    483499    }
    484500    JarFile jarFile = new JarFile(file);
     501    Manifest manifest = jarFile.getManifest();
     502    info.manifest = manifest;
    485503    Enumeration<JarEntry> entries = jarFile.entries();
    486504    while (entries.hasMoreElements())
     
    502520      list.add(file);
    503521    }
    504     if (followClassPath)
    505     {
    506       Manifest manifest = jarFile.getManifest();
    507       if (manifest != null)
    508       {
    509         Attributes attr = manifest.getMainAttributes();
    510         if (attr != null)
     522    if (followClassPath && manifest != null)
     523    {
     524      Attributes attr = manifest.getMainAttributes();
     525      if (attr != null)
     526      {
     527        String cp = attr.getValue(Attributes.Name.CLASS_PATH);
     528        log.debug("Class path of JAR file '" + file + "': " + cp);
     529        if (cp != null)
    511530        {
    512           String cp = attr.getValue(Attributes.Name.CLASS_PATH);
    513           log.debug("Class path of JAR file '" + file + "': " + cp);
    514           if (cp != null)
     531          String[] cps = cp.split("\\s+");
     532          for (int i = 0; i < cps.length; ++i)
    515533          {
    516             String[] cps = cp.split("\\s+");
    517             for (int i = 0; i < cps.length; ++i)
     534            if (cps[i] != null && !cps[i].trim().equals(""))
    518535            {
    519               if (cps[i] != null && !cps[i].trim().equals(""))
    520               {
    521                 loadJarFile(new File(file.getParent(), cps[i]), false);
    522               }
     536              loadJarFile(new File(file.getParent(), cps[i]), false);
    523537            }
    524538          }
    525           if (file == mainJarFile)
    526           {
    527             delegateFirst = Values.getBoolean(attr.getValue("X-Delegate-First"), delegateFirst);
    528           }
     539        }
     540        if (file == mainJarFile)
     541        {
     542          delegateFirst = Values.getBoolean(attr.getValue("X-Delegate-First"), delegateFirst);
    529543        }
    530544      }
     
    581595    }
    582596  }
     597  /**
     598    Define the package with the given name using information from a
     599    manifest for vendor, title and version. The package should not
     600    already exist.
     601    @param name The name of the package
     602    @param mf An optional manifest
     603    @return A package
     604    @since 2.16
     605  */
     606  private Package definePackage(String name, Manifest mf)
     607  {
     608    String specTitle = null;
     609    String specVersion = null;
     610    String specVendor = null;
     611    String implTitle = null;
     612    String implVersion = null;
     613    String implVendor = null;
     614    if (mf != null)
     615    {
     616      // Check if attributes are defined for the given package path
     617      String path = name.replace('.', '/') + "/";
     618      Attributes attr = mf.getAttributes(path);
     619      if (attr != null)
     620      {
     621        specTitle = attr.getValue(Name.SPECIFICATION_TITLE);
     622        specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
     623        specVendor = attr.getValue(Name.SPECIFICATION_VENDOR);
     624        implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE);
     625        implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
     626        implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR);
     627      }
     628      // Check global attributes
     629      attr = mf.getMainAttributes();
     630      if (attr != null)
     631      {
     632          if (specTitle == null) specTitle = attr.getValue(Name.SPECIFICATION_TITLE);
     633          if (specVersion == null) specVersion = attr.getValue(Name.SPECIFICATION_VERSION);
     634          if (specVendor == null) specVendor = attr.getValue(Name.SPECIFICATION_VENDOR);
     635          if (implTitle == null) implTitle = attr.getValue(Name.IMPLEMENTATION_TITLE);
     636          if (implVersion == null) implVersion = attr.getValue(Name.IMPLEMENTATION_VERSION);
     637          if (implVendor == null) implVendor = attr.getValue(Name.IMPLEMENTATION_VENDOR);
     638      }
     639    }
     640    return definePackage(name, specTitle, specVersion, specVendor, implTitle, implVersion, implVendor, null);
     641  }
    583642 
    584643  private Class<?> loadClassInternal(ClassLoader loader, String name)
     
    609668  {
    610669    final File jarFile;
     670    Manifest manifest;
    611671    final boolean existed;
    612672    final long lastModified;
  • trunk/src/test/TestJarClassLoader.java

    r5013 r5394  
    4646   
    4747    test_load("JarPlugin.jar", "JarPlugin", false, true);
    48     test_resource("JarPlugin.jar", "JarPluginManifest.txt", false, true);
     48    test_resource("JarPlugin.jar", "META-INF/MANIFEST.MF", false, true);
    4949   
    5050    // Test parent delegation
    51     test_load("JarPlugin.jar", "org.hibernate.util.FastHashMap", false, true);
     51    test_load("JarPlugin.jar", "affymetrix.calvin.exception.CalvinException", false, true);
    5252    test_resource("JarPlugin.jar", "org/hibernate/hibernate-configuration-3.0.dtd", false, false);
    5353    test_unload("JarPlugin.jar");
    54     test_load("JarPlugin.jar", "org.hibernate.util.FastHashMap", true, false);
     54    test_load("JarPlugin.jar", "affymetrix.calvin.exception.CalvinException", true, false);
    5555    test_resource("JarPlugin.jar", "org/hibernate/hibernate-configuration-3.0.dtd", true, false);
    5656   
     
    8080        throw new BaseException("Class loaded by incorrect class loader: " + loadedBy);
    8181      }
    82       write("--Load class OK");
     82      write("--Load class OK (" + className + ")");
    8383    }
    8484    catch (Throwable ex)
    8585    {
    86       write("--Load class FAILED");
     86      write("--Load class FAILED (" + className + ")");
    8787      ex.printStackTrace();
    8888      ok = false;
     
    104104        while (line != null)
    105105        {
    106           content.append(line);
     106          content.append(line).append("\n");
    107107          line = in.readLine();
    108108        }
     
    115115        if (loadContent) write("Resource content: "+content.toString());
    116116      }
    117       write("--Load resource OK");
     117      write("--Load resource OK (" + name + ")");
    118118    }
    119119    catch (Throwable ex)
    120120    {
    121       write("--Load resource FAILED");
     121      write("--Load resource FAILED (" + name + ")");
    122122      ex.printStackTrace();
    123123      ok = false;
     
    154154    if (!TestUtil.getSilent())
    155155    {
    156       write("Object '"+o+"' of class '"+o.getClass().getName()+"' loaded with class loader: " +
    157           o.getClass().getClassLoader());
     156      Class c = o.getClass();
     157      write("Object '"+o+"' of class '"+c.getName()+"' in package '" + c.getPackage() +
     158          "' loaded with class loader: " + c.getClassLoader());
    158159    }
    159160  }
  • trunk/src/test/data/JarPluginManifest.txt

    r5013 r5394  
    1 Class-Path: JarPluginAbout.jar ../../lib/dist/hibernate3.jar
     1Class-Path: JarPluginAbout.jar
     2 ../../lib/dist/AffxFusion.jar
     3 ../../lib/dist/hibernate3.jar
Note: See TracChangeset for help on using the changeset viewer.