• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Tim Cooke
  • paul wheaton
  • Paul Clapham
  • Ron McLeod
Sheriffs:
  • Jeanne Boyarsky
  • Liutauras Vilda
Saloon Keepers:
  • Tim Holloway
  • Carey Brown
  • Roland Mueller
  • Piet Souris
Bartenders:

IllegalAccessException when attempting to use newInstance()

 
Ranch Hand
Posts: 218
13
VI Editor
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Could anyone tell me why one of these examples works and the other doesn't?

My first example compiles but throws an exception.

According to the api for Class
'IllegalAccessException is thrown  if the class or its nullary constructor is not accessible.'

I'm thinking that the fact that the dog barks at line 7 demonstrates that neither of those things is true.

My second example, (simplified from the example at TutorialsPoint ) compiles and runs ok.


Seems to me however that the second example is doing the same thing.
 
Marshal
Posts: 80865
505
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That tutorial is horribly out of date if it recommends using java.util.Date. A dreadful class, which was largely superseded by Calendar nearly twenty years ago, and should have been completely superseded by newer classes about five years ago. It also doesn't tell you that you oughtn't to use newInstance() any more.
Anyway, Date is a public class in its package and it has a public constructor without any arguments, so it is accessible to newInstance(). So far, so good. So  tried your code and didn't get any exceptions.
 
Richard Hayward
Ranch Hand
Posts: 218
13
VI Editor
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks for the tips about Date. It's not primarily Date I was interested in, any class would do. I just came across that code snippet when googling for an example of the use of newInstance().

Campbell Ritchie wrote: It also doesn't tell you that you oughtn't to use newInstance() any more.


ok. That link for the java 12 api shows newInstance as deprecated since java 9. I'm using a java 8 compiler.

Campbell Ritchie wrote:
So  tried your code and didn't get any exceptions.


Should still work though shouldn't it?

 
Bartender
Posts: 15743
368
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The error message tells you exactly why it can't create an instance of NewInstanceTest1$Dog: It has the private access modifier.
 
Campbell Ritchie
Marshal
Posts: 80865
505
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So why could I get Java12 to create an instance without any exceptions last night? I shall try again.

Campbell's Java12/Linux/x64 wrote:[critchie@...~]$ pluma NewInstanceTest2.java&
[1] 31972
[critchie@... ~]$ javac NewInstanceTest2.java
Note: NewInstanceTest2.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
[critchie@... ~]$ java NewInstanceTest2
Fri Apr 26 10:12:58 BST 2019
Fri Apr 26 10:12:58 BST 2019
[critchie@...~]$ pluma NewInstanceTest1.java&
[2] 32147
[critchie@... ~]$ javac NewInstanceTest1.java
Note: NewInstanceTest1.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
[2]+  Done                    pluma NewInstanceTest1.java
[critchie@... ~]$ java NewInstanceTest1
woof!
[critchie@... ~]$  

Code used copied'n'pasted from above post unchanged. Insert “System.out.println(o);” after line 10 in first class, and I get this instead:-

. . . java NewInstanceTest1
woof!
NewInstanceTest1$Dog@4d7e1886

Note typical output from un‑overridden toString() method.
 
Rancher
Posts: 4801
50
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Maybe the code has changed?
 
Stephan van Hulst
Bartender
Posts: 15743
368
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Wow, apparently this was fixed by a feature implementation in Java 11: http://openjdk.java.net/jeps/181

I'm guessing that direct access to private members of nested/enclosing classes was implemented through bridge-methods before Java 11. Bridge methods are added by the compiler, so they don't account for reflective access.

Java 11 added special access scopes that allow access to these private members without using bridge methods, which would also work when using reflection.

[edit]

From the JEP I linked to above:

JEP 181 wrote:
A further consequence of the lack of JVM support for private access within a nest, is that core reflection also denies access.
A reflective method invocation (using java.lang.reflect.Method.invoke) from one nestmate to another throws IllegalAccessError (unless access control has been disabled).
This is surprising given that reflective invocations should behave the same as source level invocations.

 
Richard Hayward
Ranch Hand
Posts: 218
13
VI Editor
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
So could I clarify this?

Stephan van Hulst wrote:The error message tells you exactly why it can't create an instance of NewInstanceTest1$Dog: It has the private access modifier.



I didn't understand Stephan's response here because I thought that as far as inner classes are concerned, the outer class can see members of an inner class, even if they are declared private. For example:


the dog barks. Therefore, from my initial post


I was thinking that because Dog is an inner class, the outer class should be able access all it methods. Is the problem that it's Dog that's the inner class, not dogClass?


 
Sheriff
Posts: 22862
132
Eclipse IDE Spring TypeScript Quarkus Java Windows
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Reflection in general is more limited than compiled code. While you can easily call a private method directly, if you retrieve that method through reflection you must first make it accessible (setAccessible(true)).
 
Richard Hayward
Ranch Hand
Posts: 218
13
VI Editor
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks to all for your help on this thread.

Seems I should spend a bit of time exploring what levels of access are given to objects when reflection is used, as opposed to when it's not.
 
Campbell Ritchie
Marshal
Posts: 80865
505
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Maybe it would be better simply to regard reflection as problematic and use it as little as possible.
 
With a little knowledge, a cast iron skillet is non-stick and lasts a lifetime.
reply
    Bookmark Topic Watch Topic
  • New Topic