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

Impossible to use spreadsheet component from another classloader


    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Normal Normal
    • 3.9.2
    • 3.9.1
    • ZSS Server Side
    • None

      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

            henrichen henrichen
            sirvaulterscoff sirvaulterscoff
            1 Vote for this issue
            2 Start watching this issue