मेरे पास Formula
है, जो पैकेज javaapplication4
में स्थित है, जिसे मैं URLClassLoader के साथ लोड करता हूं। हालांकि, जब मैं इसे उसी पैकेज में स्थित किसी अन्य श्रेणी Test1
से कॉल करता हूं, तो मैं उन विधियों तक नहीं पहुंच सकता जिनके पास डिफ़ॉल्ट एक्सेस संशोधक है (मैं सार्वजनिक विधियों तक पहुंच सकता हूं)।URLClassLoader और पैकेज-निजी विधियों की पहुंच
java.lang.IllegalAccessException:
मैं निम्न अपवाद प्राप्त कक्षा javaapplication4.Test1 संशोधक के साथ वर्ग javaapplication4.Formula के एक सदस्य तक नहीं पहुँच सकता ""
मैं कैसे कर सकता है उसी पैकेज से रनटाइम पर लोड की गई कक्षा के पैकेज-निजी विधियों का उपयोग करें?
मुझे लगता है कि यह एक अलग वर्ग लोडर का उपयोग करने में एक समस्या है, लेकिन यह सुनिश्चित नहीं है कि (मैंने URLClassLoader के माता-पिता को क्यों सेट किया है)।
SSCCE मुद्दा (विंडोज पथ) के पुनरुत्पादन - मुझे लगता है कि इस मुद्दे को loadClass
विधि में है:
public class Test1 {
private static final Path TEMP_PATH = Paths.get("C:/temp/");
public static void main(String[] args) throws Exception {
String thisPackage = Test1.class.getPackage().getName();
String className = thisPackage + ".Formula"; //javaapplication4.Formula
String body = "package " + thisPackage + "; "
+ "public class Formula { "
+ " double calculateFails() { "
+ " return 123; "
+ " } "
+ " public double calculate() {"
+ " return 123; "
+ " } "
+ "} ";
compile(className, body, TEMP_PATH);
Class<?> formulaClass = loadClass(className, TEMP_PATH);
Method calculate = formulaClass.getDeclaredMethod("calculate");
double value = (double) calculate.invoke(formulaClass.newInstance());
//next line prints 123
System.out.println("value = " + value);
Method calculateFails = formulaClass.getDeclaredMethod("calculateFails");
//next line throws exception:
double valueFails = (double) calculateFails.invoke(formulaClass.newInstance());
System.out.println("valueFails = " + valueFails);
}
private static Class<?> loadClass(String className, Path path) throws Exception {
URLClassLoader loader = new URLClassLoader(new URL[]{path.toUri().toURL()}, Test1.class.getClassLoader());
return loader.loadClass(className);
}
private static void compile(String className, String body, Path path) throws Exception {
List<JavaSourceFromString> sourceCode = Arrays.asList(new JavaSourceFromString(className, body));
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
fileManager.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(path.toFile()));
boolean ok = compiler.getTask(null, fileManager, null, null, null, sourceCode).call();
System.out.println("compilation ok = " + ok);
}
public static class JavaSourceFromString extends SimpleJavaFileObject {
final String code;
JavaSourceFromString(String name, String code) {
super(URI.create("string:///" + name.replace('.', '/') + JavaFileObject.Kind.SOURCE.extension),
JavaFileObject.Kind.SOURCE);
this.code = code;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
}
}
क्या आपने 'URLClassLoader.newInstance()' का उपयोग करने का प्रयास किया है? (संपादित करें: शायद कोई फर्क नहीं पड़ता) – fge
@fge वही व्यवहार – assylias
आपका कोड मेरे लिए संकलित नहीं हुआ था, मुझे हर जगह 'डबल' से 'डबल'' (ओरेकल जेडीके 1.7u10) – fge