Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
public interface GeneratedClassClassLoaderCapture {
    void capture(String className, byte[] bytes);
}

The example of capturing class loader service may look like this:

Code Block
languagejava
public class DumpingClassLoaderCapturer implements GeneratedClassClassLoaderCapture {
    private final Map<String, byte[]> classes = new ConcurrentHashMap<>();
    
    public void dumpTo(File file) throws IOException {
        if (!file.exists() || !file.isDirectory()) {
            throw new IllegalArgumentException("The dump location does not exist or is not a directory: " + file);
        }
        
        for (Map.Entry<String, byte[]> entry: classes.entrySet()) {
            final Path path = file.toPath().resolve(StringUtils.periodToSlashes(entry.getKey()) + ".class");
            Files.createDirectories(path.getParent());
            
            try (OutputStream out = Files.newOutputStream(path, StandardOpenOption.CREATE)) {
                out.write(entry.getValue());
            }
        }
    }

    @Override
    public void capture(String className, byte[] bytes) {
        classes.putIfAbsent(className, bytes);
    }
}

The stored generated classes should be injected at build time, whereas the following extensions replace dynamic class generation with class loading of the captured (generated) classes at runtime:

...

Code Block
languagejava
 final Bus bus = ...; /* Bus instance */
 bus.setExtension(new WrapperHelperClassLoader(bus), WrapperHelperCreator.class);
 bus.setExtension(new ExtensionClassLoader(bus), ExtensionClassCreator.class);
 bus.setExtension(new ExceptionClassLoader(bus), ExceptionClassCreator.class);
 bus.setExtension(new GeneratedWrapperClassLoaderWrapperClassLoader(bus), WrapperClassCreator.class);
 bus.setExtension(new FactoryClassLoader(bus), FactoryClassCreator.class);
 bus.setExtension(new GeneratedNamespaceClassLoader(bus), NamespaceClassCreator.class);

You may run into dynamic class generation in a few cases:

  • when using JaxWsDynamicClientFactory (fully dynamic clients)
  • when using request / response wrappers and fault exception wrappers (which may not generated at build time)