Menu

patch for GeneralLegacyIndexCodes.loadCodes

2011-06-09
2018-01-08
  • Mihail Andreev

    Mihail Andreev - 2011-06-09

    Hello and thank you for such great Java module!

    I have small patch to suggest.
    ---------------------->>>
    ===================================================================
    --- src/com/healthmarketscience/jackcess/GeneralLegacyIndexCodes.java
    +++ src/com/healthmarketscience/jackcess/GeneralLegacyIndexCodes.java
    @@ -326,7 +326,7 @@

    reader = new BufferedReader(
    new InputStreamReader(
    - Thread.currentThread().getContextClassLoader()
    + GeneralLegacyIndexCodes.class.getClassLoader()
    .getResourceAsStream(codesFilePath), "US-ASCII"));

    int start = asUnsignedChar(firstChar);
    <<< -------------------------------------

    Some comments. My setup includes application server, application which has
    Java API to develop custom blocks so it can be deploy into the application as
    jar file (or set of jar files).
    Application server and application both are not open source and not all
    details of the deployment process are documented, but it looks like class
    loader of the current thread and the Jackcess library class loader are not the
    same.
    and as the code is called in a static initialization my function throws
    java.lang.ExceptionInInitializerError at run time

    The stack trace goes like that:

    java.lang.ExceptionInInitializerError
    at com.healthmarketscience.jackcess.GeneralLegacyIndexCodes.getCharHandler(Gen
    eralLegacyIndexCodes.java:302)
    at com.healthmarketscience.jackcess.GeneralLegacyIndexCodes.writeNonNullIndexT
    extValue(GeneralLegacyIndexCodes.java:514)
    at com.healthmarketscience.jackcess.IndexData$GenLegTextColumnDescriptor.write
    NonNullValue(IndexData.java:1547)
    at com.healthmarketscience.jackcess.IndexData$ColumnDescriptor.writeValue(Inde
    xData.java:1311)
    <...skiped...>
    Caused by: java.lang.NullPointerException
    at java.io.Reader.<init>(Reader.java:61)
    at java.io.InputStreamReader.<init>(InputStreamReader.java:80)
    at com.healthmarketscience.jackcess.GeneralLegacyIndexCodes.loadCodes(GeneralL
    egacyIndexCodes.java:327)
    at com.healthmarketscience.jackcess.GeneralLegacyIndexCodes$Codes.<clinit&g
    t;(GeneralLegacyIndexCodes.java:278)
    ... 92 more

    I recompiled Jackcess 1.2.4 with this one-line patch and the problem is gone.

    Mike

     
    • Alejandro Domínguez

      Do you resolve it?

       
  • James Ahlborn

    James Ahlborn - 2011-06-10

    just curious. can you create new databases without a problem? the reason i ask
    is because the database creation code uses the same call
    "Thread.currentThread().getContextClassLoader().getResourceAsStream()".

     
  • James Ahlborn

    James Ahlborn - 2011-06-10

    FYI, i've checked in changes which will be in the 1.2.5 release which will try
    both the class's classloader and the Thread context classloader.

     
  • Mihail Andreev

    Mihail Andreev - 2011-06-14

    for my task I only need to read MS Access file.
    so I didn't try the creation code though I saw the same
    Thread.currentThread().getContextClassLoader() call in this place.
    actually I'm quite sure that the result will be the same exception.
    do you want me to try it in my environment?

     
  • Mihail Andreev

    Mihail Andreev - 2011-06-14

    Thank you for the update!

    but I'm just wondering is it really make sense to try Thread context
    classloader? as I see it the class's classloader must have the resource.

     
  • James Ahlborn

    James Ahlborn - 2011-06-14

    Sometimes app servers do weird things with classloaders (that's why i was
    using the context classloader). i expect that most lookups should work with
    the class classloader, but, just to be safe, i left the old code there as well
    as a backstop.

     
  • MeW

    MeW - 2014-05-27

    This issue resurfaces in the latest build 2.0.4. The code has moved somehwat into DatabaseImpl.java. I've patched the getResourceAsStream to prevent a nil pointer exception:

    /**
     * When used in a jar, the getClassLoader may return null.
     * Make sure to check this before calling methods.
     */
    

    static InputStream getResourceAsStream(String resourceName)
    throws IOException
    {
    InputStream stream = null;

    if (DatabaseImpl.class.getClassLoader() != null) {
        stream = DatabaseImpl.class.getClassLoader()
                .getResourceAsStream(resourceName);
    }
    
    if(stream == null) {
    
        stream = Thread.currentThread().getContextClassLoader()
        .getResourceAsStream(resourceName);
    
        if(stream == null) {
        throw new IOException("Could not load jackcess resource " +
                              resourceName);
      }
    
    }
    
    return stream;
    

    }

     
    • James Ahlborn

      James Ahlborn - 2014-05-27

      You have a situation where the classloader for the DatabaseImpl class is null? That doesn't seem possible. as far as i understand, that can only return null for system classes.

       

      Last edit: James Ahlborn 2014-05-27

Log in to post a comment.