code: private ArrayList<IIOMetadata> readExif( IIOMetadataNode app1EXIFNode ) {
          // Set up input skipping EXIF ID 6-byte sequence.
          byte[] app1Params = (byte[]) app1EXIFNode.getUserObject();
  
          MemoryCacheImageInputStream app1EXIFInput = new MemoryCacheImageInputStream(new ByteArrayInputStream(app1Params, 6,
                  app1Params.length - 6));
  
          // only the tiff reader knows how to interpret the exif metadata
          ImageReader tiffReader = null;
          Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("tiff");
  
          while( readers.hasNext() ) {
              tiffReader = (ImageReader) readers.next();
              if (tiffReader.getClass().getName().startsWith("com.sun.media")) {
                  // Break on finding the core provider.
                  break;
              }
          }
          if (tiffReader == null) {
              throw new RuntimeException("Cannot find core TIFF reader!");
          }
  
          ArrayList<IIOMetadata> out = new ArrayList<IIOMetadata>(1);
  
          tiffReader.setInput(app1EXIFInput);
  
          IIOMetadata tiffMetadata = null;
  
          try {
              tiffMetadata = tiffReader.getImageMetadata(0);
              // IIOMetadata meta = tiffReader.getImageMetadata(0);
              TIFFImageReadParam rParam = (TIFFImageReadParam) tiffReader.getDefaultReadParam();
              rParam.setTIFFDecompressor(null);
          } catch (IOException e) {
              e.printStackTrace();
          };
  
          tiffReader.dispose();
  
          out.add(0, tiffMetadata);
  
          return out;
      }
docs: Private method - Reads the exif metadata for an image
  @param app1EXIFNode app1 Node of the image (where the exif data is stored)
  @return the exif metadata