(java) inheritance runtime problem

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

(java) inheritance runtime problem

plamaizere
(parboiled for java 0.11.0)

Hello all, hello Mathias.

I've got a problem at runtime with rules inheritance:

I'm trying to use the following hierarchy of rules:

java.lang.Object
  extended by org.parboiled.BaseActions<V>
      extended by org.parboiled.BaseParser<T>
          extended by fr.univrennes1.cri.jtacl.lib.misc.CommonRules<java.lang.Object>
              extended by fr.univrennes1.cri.jtacl.equipments.generic.GenericEquipmentShellParser
                  extended by fr.univrennes1.cri.jtacl.equipments.cisco.pix.PixShellParser

That compiles fine but when I use the parser at runtime (ie I put some text into it) I've got an exception "java.lang.IllegalAccessError":

Exception in thread "main" java.lang.IllegalAccessError: tried to access class fr.univrennes1.cri.jtacl.equipments.generic.GenericEquipmentShellParser$1 from class fr.univrennes1.cri.jtacl.equipments.cisco.pix.PixShellParser$$parboiled
        at fr.univrennes1.cri.jtacl.equipments.cisco.pix.PixShellParser$$parboiled.CommandHelp(Unknown Source)
        at fr.univrennes1.cri.jtacl.equipments.cisco.pix.PixShellParser.CommandLine(PixShellParser.java:32)
        at fr.univrennes1.cri.jtacl.equipments.cisco.pix.PixShellParser$$parboiled.CommandLine(Unknown Source)
        at fr.univrennes1.cri.jtacl.equipments.cisco.pix.PixShell.shellCommand(PixShell.java:158)
        at fr.univrennes1.cri.jtacl.equipments.generic.GenericEquipment.runShell(GenericEquipment.java:427)
        at fr.univrennes1.cri.jtacl.shell.Shell.equipmentCommand(Shell.java:452)
        at fr.univrennes1.cri.jtacl.shell.Shell.parseShellCommand(Shell.java:989)
        at fr.univrennes1.cri.jtacl.shell.Shell.runFromFile(Shell.java:1048)
        at fr.univrennes1.cri.jtacl.shell.Shell.run(Shell.java:1097)
        at fr.univrennes1.cri.jtacl.App.main(App.java:52)

This does not happen for one rule ("commandHelp" rule), I don't know why.

Also, If I put the class "GenericEquipmentShellParser" in the same package as the child class, it works fine.

I really don't understand this, I've tried to make all the fields public in "GenericEquipmentShellParser" but this does not change anything.

Any tips would be welcome...
Regards.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: (java) inheritance runtime problem

mathias
Administrator
Hi,

sorry for the delay in responding... I've been awfully busy these last days.

The error you are seeing stems from an undocumented limitation of parboiled that is very rarely hit and whose fix would be quite work-intensive.
Let me explain what is happening:

During parser extension parboiled gathers up all rule methods of your parser class (the PixShellParser class in your case), including all the ones inherited from ancestor classes. parboiled then rewrites the byte code of these methods, adding caching, action wrapping and so on. The rewritten methods are defined in a synthetic class living in the same package as your parser class (in your case the synthetic class is PixShellParser$$parboiled)

If your parser class lives in package A and extends another parser class that lives in package B there is a chance that, during parser extension, byte code that contains instructions local to package B are transplanted to package A. If the manipulated class members or classes are not legally visible from package A you will get the exception you are seeing.

In your case GenericEquipmentShellParser contains a rule method that contains a definition of an anonymous inner class. Anonymous inner classes are never public and therefore not visible from the package of the PixShellParser.

Here are the options of what you can do to fix the problem:
- Move the creation of the anonymous inner class out of its rule method into another non-private method and call this new method from the rule method.
- Turn the anonymous inner class into an explicit inner class and give this class public or protected access.
- Move the PixShellParser into the same package as the GenericEquipmentShellParser (as you have already discovered).

parboiled should probably issue proper error message for these cases.
I've created a github issue for this (https://github.com/sirthias/parboiled/issues/23).

Cheers,
Mathias

---
[hidden email]
http://www.parboiled.org

On 06.06.2011, at 01:19, plamaizere [via parboiled users] wrote:

> (parboiled for java 0.11.0)
>
> Hello all, hello Mathias.
>
> I've got a problem at runtime with rules inheritance:
>
> I'm trying to use the following hierarchy of rules:
>
> java.lang.Object
>   extended by org.parboiled.BaseActions<V>
>       extended by org.parboiled.BaseParser<T>
>           extended by fr.univrennes1.cri.jtacl.lib.misc.CommonRules<java.lang.Object>
>               extended by fr.univrennes1.cri.jtacl.equipments.generic.GenericEquipmentShellParser
>                   extended by fr.univrennes1.cri.jtacl.equipments.cisco.pix.PixShellParser
>
> That compiles fine but when I use the parser at runtime (ie I put some text into it) I've got an exception "java.lang.IllegalAccessError":
>
> Exception in thread "main" java.lang.IllegalAccessError: tried to access class fr.univrennes1.cri.jtacl.equipments.generic.GenericEquipmentShellParser$1 from class fr.univrennes1.cri.jtacl.equipments.cisco.pix.PixShellParser$$parboiled
>         at fr.univrennes1.cri.jtacl.equipments.cisco.pix.PixShellParser$$parboiled.CommandHelp(Unknown Source)
>         at fr.univrennes1.cri.jtacl.equipments.cisco.pix.PixShellParser.CommandLine(PixShellParser.java:32)
>         at fr.univrennes1.cri.jtacl.equipments.cisco.pix.PixShellParser$$parboiled.CommandLine(Unknown Source)
>         at fr.univrennes1.cri.jtacl.equipments.cisco.pix.PixShell.shellCommand(PixShell.java:158)
>         at fr.univrennes1.cri.jtacl.equipments.generic.GenericEquipment.runShell(GenericEquipment.java:427)
>         at fr.univrennes1.cri.jtacl.shell.Shell.equipmentCommand(Shell.java:452)
>         at fr.univrennes1.cri.jtacl.shell.Shell.parseShellCommand(Shell.java:989)
>         at fr.univrennes1.cri.jtacl.shell.Shell.runFromFile(Shell.java:1048)
>         at fr.univrennes1.cri.jtacl.shell.Shell.run(Shell.java:1097)
>         at fr.univrennes1.cri.jtacl.App.main(App.java:52)
>
> This does not happen for one rule ("commandHelp" rule), I don't know why.
>
> Also, If I put the class "GenericEquipmentShellParser" in the same package as the child class, it works fine.
>
> I really don't understand this, I've tried to make all the fields public in "GenericEquipmentShellParser" but this does not change anything.
>
> Any tips would be welcome...
> Regards.
>
> If you reply to this email, your message will be added to the discussion below:
> http://users.parboiled.org/java-inheritance-runtime-problem-tp3028081p3028081.html
> To start a new topic under parboiled users, email [hidden email]
> To unsubscribe from parboiled users, click here.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: (java) inheritance runtime problem

plamaizere
Thanks a lot Mathias,

I've moved all my parsers into the same package. So it is not an issue anymore.

(I use a lot of inner Action() in the parsers and it will be painful to create a class for each, and will not be very readable)

I think it will be good to warn about this problem into the documentation of Action().
https://github.com/sirthias/parboiled/wiki/Parser-Action-Expressions

Regards.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: (java) inheritance runtime problem

mathias
Administrator
Why do you have a lot of anonymous inner Action classes?
Doesn't implicit action wrapping work for you?

Cheers,
Mathias

---
[hidden email]
http://www.parboiled.org

On 08.06.2011, at 21:10, plamaizere [via parboiled users] wrote:

> Thanks a lot Mathias,
>
> I've moved all my parsers into the same package. So it is not an issue anymore.
>
> (I use a lot of inner Action() in the parsers and it will be painful to create a class for each, and will not be very readable)
>
> I think it will be good to warn about this problem into the documentation of Action().
> https://github.com/sirthias/parboiled/wiki/Parser-Action-Expressions
>
> Regards.
>
> If you reply to this email, your message will be added to the discussion below:
> http://users.parboiled.org/java-inheritance-runtime-problem-tp3028081p3040543.html
> To start a new topic under parboiled users, email [hidden email]
> To unsubscribe from parboiled users, click here.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: (java) inheritance runtime problem

plamaizere
Hello,

In fact I was not aware about implicit actions! Looks nicer, I will convert all my (ugly) code to use them.

But are they affected by the same inheritance problem as the inner actions? That's not clear.

Thanks for the tip.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: (java) inheritance runtime problem

mathias
Administrator
> But are they affected by the same inheritance problem as the inner actions? That's not clear.

No, they are not.
If you don't use anonymous inner classes but implicit actions there is such problem.

Cheers,
Mathias

---
[hidden email]
http://www.parboiled.org

On 09.06.2011, at 18:33, plamaizere [via parboiled users] wrote:

> Hello,
>
> In fact I was not aware about implicit actions! Looks nicer, I will convert all my (ugly) code to use them.
>
> But are they affected by the same inheritance problem as the inner actions? That's not clear.
>
> Thanks for the tip.
>
>
>
> If you reply to this email, your message will be added to the discussion below:
> http://users.parboiled.org/java-inheritance-runtime-problem-tp3028081p3044711.html
> To start a new topic under parboiled users, email [hidden email]
> To unsubscribe from parboiled users, click here.

Loading...