Note that there are some explanatory texts on larger screens.

plurals
  1. POURLClassLoader and accessibility of package-private methods
    primarykey
    data
    text
    <p>I have a class <code>Formula</code>, located in package <code>javaapplication4</code>, which I load with a URLClassLoader. However, when I call it from another class <code>Test1</code>, located in the same package, I can't access its methods that have a default access modifier (I can access public methods).</p> <p>I get the following exception:</p> <blockquote> <p>java.lang.IllegalAccessException: Class javaapplication4.Test1 can not access a member of class javaapplication4.Formula with modifiers ""</p> </blockquote> <p><strong>How can I access package-private methods of a class loaded at runtime from the same package?</strong></p> <p>I suppose it is a problem with using a different class loader, but not sure why (I have set the parent of the URLClassLoader).</p> <p>SSCCE reproducing the issue (Windows paths) - I suppose the issue is in the <code>loadClass</code> method:</p> <pre><code>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&lt;?&gt; 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&lt;?&gt; 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&lt;JavaSourceFromString&gt; 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; } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload