Skip to content

Instantly share code, notes, and snippets.

@TronPaul
Created February 27, 2020 06:07
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save TronPaul/008bc72238d0adcfbbcd2c8ea0219eb0 to your computer and use it in GitHub Desktop.
Save TronPaul/008bc72238d0adcfbbcd2c8ea0219eb0 to your computer and use it in GitHub Desktop.
Substitutions needed to run Lucene 8.4.1 on a GraalVM native image
package org.apache.lucene.util;
import java.lang.reflect.Constructor;
import java.lang.reflect.UndeclaredThrowableException;
public final class AttributeFactoryHelpers {
static final AttributeFactory DEFAULT = new DefaultAttributeFactory();
static final Constructor<? extends AttributeImpl> findAttributeImplCtor(Class<? extends AttributeImpl> clazz) {
try {
return clazz.getConstructor();
} catch (NoSuchMethodException e) {
throw new IllegalArgumentException("Cannot lookup accessible no-arg constructor for: " + clazz.getName(), e);
}
}
static final class DefaultAttributeFactory extends AttributeFactory {
private final ClassValue<Constructor<? extends AttributeImpl>> constructors = new ClassValue<Constructor<? extends AttributeImpl>>() {
@Override
protected Constructor<? extends AttributeImpl> computeValue(Class<?> attClass) {
return AttributeFactoryHelpers.findAttributeImplCtor(findImplClass(attClass.asSubclass(Attribute.class)));
}
};
DefaultAttributeFactory() {}
@Override
public AttributeImpl createAttributeInstance(Class<? extends Attribute> attClass) {
try {
return constructors.get(attClass).newInstance();
} catch (Error | RuntimeException e) {
throw e;
} catch (Throwable e) {
throw new UndeclaredThrowableException(e);
}
}
private Class<? extends AttributeImpl> findImplClass(Class<? extends Attribute> attClass) {
try {
return Class.forName(attClass.getName() + "Impl", true, attClass.getClassLoader()).asSubclass(AttributeImpl.class);
} catch (ClassNotFoundException cnfe) {
throw new IllegalArgumentException("Cannot find implementing class for: " + attClass.getName());
}
}
}
public static <A extends AttributeImpl> AttributeFactory getStaticImplementation(AttributeFactory delegate, Class<A> clazz) {
final Constructor<? extends AttributeImpl> constr = AttributeFactoryHelpers.findAttributeImplCtor(clazz);
return new AttributeFactory.StaticImplementationAttributeFactory<A>(delegate, clazz) {
@Override
protected A createInstance() {
try {
return (A) constr.newInstance();
} catch (Error | RuntimeException e) {
throw e;
} catch (Throwable e) {
throw new UndeclaredThrowableException(e);
}
}
};
}
}
package org.apache.lucene.util;
import com.oracle.svm.core.annotate.Alias;
import com.oracle.svm.core.annotate.Delete;
import com.oracle.svm.core.annotate.RecomputeFieldValue;
import com.oracle.svm.core.annotate.Substitute;
import com.oracle.svm.core.annotate.TargetClass;
import java.lang.invoke.MethodHandle;
import java.lang.reflect.Constructor;
import java.lang.reflect.UndeclaredThrowableException;
import java.util.Arrays;
@TargetClass(AttributeFactory.class)
final class AttributeFactorySubstitutions {
@Alias
@RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FromAlias, isFinal = true)
public static AttributeFactory DEFAULT_ATTRIBUTE_FACTORY = new AttributeFactory() {
private final ClassValue<Constructor<? extends AttributeImpl>> constructors = new ClassValue<Constructor<? extends AttributeImpl>>() {
@Override
protected Constructor<? extends AttributeImpl> computeValue(Class<?> attClass) {
return AttributeFactoryHelpers.findAttributeImplCtor(findImplClass(attClass.asSubclass(Attribute.class)));
}
};
@Override
public AttributeImpl createAttributeInstance(Class<? extends Attribute> attClass) {
try {
return constructors.get(attClass).newInstance();
} catch (Error | RuntimeException e) {
throw e;
} catch (Throwable e) {
throw new UndeclaredThrowableException(e);
}
}
private Class<? extends AttributeImpl> findImplClass(Class<? extends Attribute> attClass) {
try {
return Class.forName(attClass.getName() + "Impl", true, attClass.getClassLoader()).asSubclass(AttributeImpl.class);
} catch (ClassNotFoundException cnfe) {
throw new IllegalArgumentException("Cannot find implementing class for: " + attClass.getName());
}
}
};
@Substitute
public static <A extends AttributeImpl> AttributeFactory getStaticImplementation(AttributeFactory delegate, Class<A> clazz) {
final Constructor<? extends AttributeImpl> constr = AttributeFactoryHelpers.findAttributeImplCtor(clazz);
return new AttributeFactory.StaticImplementationAttributeFactory<A>(delegate, clazz) {
@Override
protected A createInstance() {
try {
return (A) constr.newInstance();
} catch (Error | RuntimeException e) {
throw e;
} catch (Throwable e) {
throw new UndeclaredThrowableException(e);
}
}
};
}
@Delete
static final MethodHandle findAttributeImplCtor(Class<? extends AttributeImpl> clazz) {
throw new RuntimeException();
}
}
package org.apache.lucene.store;
import com.oracle.svm.core.annotate.Alias;
import com.oracle.svm.core.annotate.RecomputeFieldValue;
import com.oracle.svm.core.annotate.Substitute;
import com.oracle.svm.core.annotate.TargetClass;
@TargetClass(MMapDirectory.class)
final class MMapDirectorySubstitutions {
@Alias
@RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FromAlias, isFinal = true)
private static ByteBufferGuard.BufferCleaner CLEANER = null;
@Alias
@RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FromAlias, isFinal = true)
private static boolean UNMAP_SUPPORTED = false;
@Substitute
private static Object unmapHackImpl() {
return "Manually disabled for graalvm";
}
}
package org.apache.lucene.analysis;
import com.oracle.svm.core.annotate.Alias;
import com.oracle.svm.core.annotate.RecomputeFieldValue;
import com.oracle.svm.core.annotate.TargetClass;
import org.apache.lucene.analysis.tokenattributes.PackedTokenAttributeImpl;
import org.apache.lucene.util.AttributeFactory;
import org.apache.lucene.util.AttributeFactoryHelpers;
@TargetClass(TokenStream.class)
final class TokenStreamSubstitutions {
@Alias
@RecomputeFieldValue(kind = RecomputeFieldValue.Kind.FromAlias, isFinal = true)
public static AttributeFactory DEFAULT_TOKEN_ATTRIBUTE_FACTORY = AttributeFactoryHelpers.getStaticImplementation(AttributeFactory.DEFAULT_ATTRIBUTE_FACTORY, PackedTokenAttributeImpl.class);
}
@TronPaul
Copy link
Author

I hope my 2 nights of pain and sadness help others avoid the same

@serefarikan
Copy link

many thanks for this Paul!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment