1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package org.apache.shardingsphere.infra.expr.espresso; 19 20 import lombok.SneakyThrows; 21 22 /** 23 * Reflect Context. 24 * Avoid using JDK21 bytecode during compilation. Refer to `org.graalvm.polyglot.Context`. 25 */ 26 public final class ReflectContext implements AutoCloseable { 27 28 private static final String CONTEXT_CLASS_NAME = "org.graalvm.polyglot.Context"; 29 30 private final Object contextInstance; 31 32 /** 33 * This method is a simulation of the following operation. 34 * // CHECKSTYLE:OFF 35 * <pre class="code"> 36 * private final Context context = Context.newBuilder("java") 37 * .allowAllAccess(true) 38 * .allowValueSharing(false) 39 * .option("java.Classpath", JAVA_CLASSPATH) 40 * .build(); 41 * </pre> 42 * // CHECKSTYLE:ON 43 * TODO <a href="https://github.com/oracle/graal/issues/4555">oracle/graal#4555</a> not yet closed. 44 * Maybe sometimes shardingsphere need `.option("java.Properties.org.graalvm.home", System.getenv("JAVA_HOME")). 45 * 46 * @param javaClassPath java class path 47 */ 48 @SneakyThrows 49 public ReflectContext(final String javaClassPath) { 50 Object builderInstance = Class.forName(CONTEXT_CLASS_NAME) 51 .getMethod("newBuilder", String[].class) 52 .invoke(null, (Object) new String[]{"java"}); 53 builderInstance = builderInstance.getClass() 54 .getMethod("allowAllAccess", boolean.class) 55 .invoke(builderInstance, true); 56 builderInstance = builderInstance.getClass() 57 .getMethod("allowValueSharing", boolean.class) 58 .invoke(builderInstance, false); 59 builderInstance = builderInstance.getClass() 60 .getMethod("option", String.class, String.class) 61 .invoke(builderInstance, "java.Classpath", javaClassPath); 62 contextInstance = builderInstance.getClass() 63 .getMethod("build") 64 .invoke(builderInstance); 65 } 66 67 /** 68 * Returns a value that represents the top-most bindings of a language. 69 * 70 * @param languageId languageId 71 * @return {@link org.apache.shardingsphere.infra.expr.espresso.ReflectValue} 72 */ 73 @SneakyThrows 74 public ReflectValue getBindings(final String languageId) { 75 Object valueInstance = Class.forName(CONTEXT_CLASS_NAME) 76 .getMethod("getBindings", String.class) 77 .invoke(contextInstance, languageId); 78 return new ReflectValue(valueInstance); 79 } 80 81 @Override 82 @SneakyThrows 83 public void close() { 84 Class.forName(CONTEXT_CLASS_NAME).getMethod("close").invoke(contextInstance); 85 } 86 }