Uploaded image for project: 'ZK Spreadsheet'
  1. ZK Spreadsheet
  2. ZSS-1319

Impossible to use spreadsheet component from another classloader

    Details

    • Type: Bug
    • Status: Closed
    • Priority: Normal
    • Resolution: Fixed
    • Affects Version/s: 3.9.1
    • Fix Version/s: 3.9.2
    • Component/s: ZSS Server Side
    • Labels:
      None

      Description

      I've working on a custom plugin for my web-application (classic, servlet 3.0 packed in a war) with zk spreadsheet added functionality.
      So i have a war with all the core dependencies, including zk, zcommon. Also i have an uber-jar (created using maven shade plugin) which includes my custom component alongside with zss, zpoi dependencies.

      Process behind plugin-loading is simple and straightforward: during Servlet context startup i create new classloader (UrlClassLoader - UCL), adding uber-jar to classpath; that classloader becomes contextClassLoader for current thread and, as a result, is used to create spring application context.

      Since zss loaded that way (UCL) is able to see zk loaded via WebAppClassLoader (WACL) everything works fine.
      But as soon as i drop in zss ex to the same uber-jar i get a ClassNotFoundException: org.zkoss.zssex.ui.impl.UserActionManagerCtrlImpl
      with following stacktrace

              at java.lang.Class.forName0(Native Method)
              at java.lang.Class.forName(Class.java:195)
              at org.zkoss.lang.Classes.newInstance(Classes.java:212)
              at org.zkoss.zss.ui.Spreadsheet.getUserActionManagerCtrl(Spreadsheet.java:494)
              at org.zkoss.zss.ui.Spreadsheet.initComponentActionHandler(Spreadsheet.java:449)
              at org.zkoss.zss.ui.Spreadsheet.<init>(Spreadsheet.java:423)
      

      Following steps leads to the problem
      1. zssex defines metainfo/zk/config.xml, wich in turn defines library property org.zkoss.zss.ui.UserActionManagerCtrl.class as org.zkoss.zssex.ui.impl.UserActionManagerCtrlImpl
      2. Spreadsheet (loaded by UCP) tries to instantiate aforementioned class calling Classes.newInstance(String, Class[], Object[]) (loaded by WACL)
      3. Later calls Class.forName, which uses Reflection.getCallerClass() to determine apropriate class loader. Since org.zkoss.lang.Classes is loaded by WACL is tries to resolve org.zkoss.zssex.ui.impl.UserActionManagerCtrlImpl using said classloader, causing operation to fail

      Suggested aproach:
      moving Class.forName to org.zkoss.zss.ui.Spreadsheet itself (handling possible CNFE, NCDFE) and using org.zkoss.lang.Classes#newInstance(Class, Class[], Object[]) seems to solve the problem

      Will try to create PR shortly

        Activity

        Hide
        sirvaulterscoff sirvaulterscoff added a comment -
        Show
        sirvaulterscoff sirvaulterscoff added a comment - Added a PR https://github.com/zkoss/zkspreadsheet/pull/111
        Hide
        henrichen henrichen added a comment -

        Class.forName() must use Spreadsheet's defining class loader.

        Show
        henrichen henrichen added a comment - Class.forName() must use Spreadsheet's defining class loader.

          People

          • Assignee:
            henrichen henrichen
            Reporter:
            sirvaulterscoff sirvaulterscoff
          • Votes:
            1 Vote for this issue
            Watchers:
            2 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: