Uploaded image for project: 'Ignite'
  1. Ignite
  2. IGNITE-3935

ClassLoaders are not switched during object deserialization

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • 1.6
    • 2.4
    • binary
    • None

    Description

      If an object is being deserialized with ClassLoader A then this ClassLoader A will be used for the deserialization of the whole object's state, i.e., including all its fields that can be custom objects loaded by ClassLoader B.

      In a basic scenario we can have an object of some Ignite class that is presented in the classpath. That Ignite class may enclose an object that is loaded by peer-class-loading class loader. The deserialization will fail because Ignite won't switch to the peer-class-loading loader when it's needed.

      To reproduce the issue do the following:
      1. Start a remote ignite node using ./ignite.sh ../examples/config/example-ignite.xml
      2. Run the code below

      public class StreamingExample {`
      public static class StreamingExampleCacheEntryProcessor implements CacheEntryProcessor<String, Long, Object> {
          @Override
          public Object process(MutableEntry<String, Long> e, Object... arg) throws EntryProcessorException {
              Long val = e.getValue();
              e.setValue(val == null ? 1L : val + 1);
              return null;
          }
      }
      
      public static void main(String[] args) throws IgniteException, IOException {
          Ignition.setClientMode(true);
          try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) {
              IgniteCache<String, Long> stmCache = ignite.getOrCreateCache("mycache");
              try (IgniteDataStreamer<String, Long> stmr = ignite.dataStreamer(stmCache.getName())) {
                  stmr.allowOverwrite(true);
                  stmr.receiver(StreamTransformer.from(new StreamingExampleCacheEntryProcessor()));
                  stmr.addData("word", 1L);
                  System.out.println("Finished");
              }
          }
      }
      

      However if to modify this code to the following everything will work fine

      public class StreamingExample {
      
          public static class StreamingExampleCacheEntryProcessor extends StreamTransformer<String, Long> {
              @Override
              public Object process(MutableEntry<String, Long> e, Object... arg) throws EntryProcessorException {
                  System.out.println("Executed!");
                  Long val = e.getValue();
                  e.setValue(val == null ? 1L : val + 1);
                  return null;
              }
          }
      
          public static void main(String[] args) throws IgniteException, IOException {
              Ignition.setClientMode(true);
              try (Ignite ignite = Ignition.start("examples/config/example-ignite.xml")) {
                  IgniteCache<String, Long> stmCache = ignite.getOrCreateCache("mycache");
                  try (IgniteDataStreamer<String, Long> stmr = ignite.dataStreamer(stmCache.getName())) {
                      stmr.allowOverwrite(true);
                      stmr.receiver(new StreamingExampleCacheEntryProcessor());
                      stmr.addData("word", 1L);
                      System.out.println("Finished");
                  }
              }
          }
      }
      

      Attachments

        Activity

          People

            dmekhanikov Denis Mekhanikov
            dmagda Denis A. Magda
            Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Time Tracking

                Estimated:
                Original Estimate - Not Specified
                Not Specified
                Remaining:
                Remaining Estimate - 0h
                0h
                Logged:
                Time Spent - 1h
                1h