Question
Rulesware LLC
CA
Last activity: 17 May 2016 9:26 EDT
pr_assembledclasses to vtable
Hello,
In earlier versions of PRPC , each jvm would generate java code, and compile the code in prgenjava/prgenclasses.
In version 6.x we noticed that the default was to store these generated source and class files in the database. Presumably to reduce the amount of first time rule processing in the cluster.
We now see that the default behavior in 7.1.x is to use Virtual Tables .
With previous versions we could see the compiled code in the database (pr_assembledclasses), and use that information.
How can we access the generated and compiled code that resides in the VTable?
-
Like (0)
-
Share this page Facebook Twitter LinkedIn Email Copying... Copied!
Accepted Solution
Pegasystems Inc.
US
Hello Joseph
how are you? Thanks for the reply!
We do use Jacoco internally in Pega Engineering in some areas. Most developers use Eclipse here so we use EclEmma primarily for coverage analysis during product development. We also us Jacoco in automated CI & dev pipeline runs.
I've not heard of this problem. Likely because we are not using jacoco on our generated - assembled code. Instead, we use it on the product code
I highly suspect that our byte code rewriting in the product is somehow conflicting with (i assume likely...) bytecode rewriting by Jacoco. So it seems you could not use both our features related to "initialization/nofua/vtable/invokedynamic" & jacoco at the same time. The configuration setting for "initialization/nofua/vtable/invokedynamic" is used to disable a performance optimization related to When rules being called from other rules
As far as next steps. you could consider
Hello Joseph
how are you? Thanks for the reply!
We do use Jacoco internally in Pega Engineering in some areas. Most developers use Eclipse here so we use EclEmma primarily for coverage analysis during product development. We also us Jacoco in automated CI & dev pipeline runs.
I've not heard of this problem. Likely because we are not using jacoco on our generated - assembled code. Instead, we use it on the product code
I highly suspect that our byte code rewriting in the product is somehow conflicting with (i assume likely...) bytecode rewriting by Jacoco. So it seems you could not use both our features related to "initialization/nofua/vtable/invokedynamic" & jacoco at the same time. The configuration setting for "initialization/nofua/vtable/invokedynamic" is used to disable a performance optimization related to When rules being called from other rules
As far as next steps. you could consider
- If your code coverage needs are separate from your production performance requirements, you could considering using "initialization/nofua/vtable/invokedynamic" = false in your test environment with jacoco & "initialization/nofua/vtable/invokedynamic" = true in your other QA, UAT, & production environments.
I assume the purpose of jacoco coverage is to ensure your test suites exercise a realistic percentage of the assembled code. The amount of code exercised by your test cases would not vary depending upon the setting of "initialization/nofua/vtable/invokedynamic".
Hope this helps you
Thanks
Pegasystems
IN
The compiled generated and compiled code is still part of pr_assembledclasses.
Rulesware LLC
CA
That is odd. Because in PRPC 6.3 we could extract the compiled classes and generate code coverage reports.
In 6.3 the number of .java and .class files in pr_assembledclasses was one-to-one.
In 7.1 when we extract the java and classes, the number of .java files is much higher than the .class files, and our code coverage reports are coming up 0% coverage, for most class types.
Pegasystems
IN
Can we try a query like this?
select substr(pzclass, 1, length(pzclass)-5) from <schema_name>.pr_assembledclasses where pzclass like '%.java'
minus
select substr(pzclass, 1, length(pzclass)-6) from <schema_name>.pr_assembledclasses where pzclass like '%.class'
We can also try the flip the queries and check as well.
Rulesware LLC
CA
In that order we get 3,309 results.
In the reverse order we get 303 results.
Pegasystems
IN
Assuming that those java classes are not compiled because they are never referenced (probably because of rule resolution), is your code coverage actually looking if all java files are compiled or not?
Rulesware LLC
CA
It is actually looking at the compiled class files.
When the code coverage percentage is zero, it means that none of the class files have been executed. Which is impossible.
It can only be that the java is being compiled to another location, and being executed from that other location.
The documentation says that the vtable is for all rules but a few (streams and list type rules)
We get code coverage numbers for (html_harness,flowaction,corr,listview) but no other rule types.
This seems to match exactly with the list of rule types that are not yet going to the vtable.
Rulesware LLC
CA
Hello,
Is there any additional information available for this subject?
Thanks
Rulesware LLC
CA
Hello,
I was able to force the compiled class file into pr_assembledclasses by adding the following entry into prconfig.xml .
<env name="initialization/nofua/vtable/enable" value="false"/>
Pegasystems
US
>>> In 7.1 when we extract the java and classes, the number of .java files is much higher than the .class files
This sounds right to me. Let's suppose rule R1 refers to rule R2, and rulesets A and B both contain versions of R2.
If your application has ruleset A at the top of its stack, and I have ruleset B at the top of my stack, and we each access rule R1, your java for R1 will refer to the R2 in ruleset A while my java for R1 will refer to the R2 in ruleset B, and hence we each need different java's for R1 and hence there will be at least two java's for rule R1.
The above discussion assumes that class R1 implements rule R1 and hence we've shown that we need at least two java's for class R1. /Eric
Rulesware LLC
CA
Hi Eric, Our code coverage reports are coming back with zero lines of code executed for particular rule types. Things like activities and flows.
The class loader must be getting the code from another source. We need to understand where the classes are being loaded from, so that we can make adjustments to our code coverage reporting system.
Rulesware LLC
CA
The Pega docs state:
- UI (stream aspect) rules run using the Application-Based Assembly mode.
- All other rule types run in VTable.
This description appears to match up with our code coverage reports.
We get execution statistics for things like html_section, html_harness, flowaction, corr , listview .
We always get zero for things like activity, flow, model, when, ....
Rulesware LLC
CA
Still hoping for some information on how to extract the class files of the VTables. We need the access in order to determine code coverage for our functional and unit test suites.
Pegasystems Inc.
US
Hi Joseph.
I'm the designer of Vtable, and am intimately familiar with java generation & classloading int he system; I can answer your questions.
Rajiv's comment Re: pr_assembledclasses to vtable was exactly correct... all generated code for rules goes into this table. It is the only source for classes for the PRPC system classloader. If the code is not there we will not find it.
From your comment Re: pr_assembledclasses to vtable, it appears that there are more java files than there are class files.
You also said:
"We get code coverage numbers for (html_harness,flowaction,corr,listview) but no other rule types."
and you are correct, this matches up with the set of rules that are still managed outside of vtable.
I suspect that Rajiv was also correct in this comment: Re: pr_assembledclasses to vtable, I suspect that you only have generated code for a small subset of the actual rulebase.
Hi Joseph.
I'm the designer of Vtable, and am intimately familiar with java generation & classloading int he system; I can answer your questions.
Rajiv's comment Re: pr_assembledclasses to vtable was exactly correct... all generated code for rules goes into this table. It is the only source for classes for the PRPC system classloader. If the code is not there we will not find it.
From your comment Re: pr_assembledclasses to vtable, it appears that there are more java files than there are class files.
You also said:
"We get code coverage numbers for (html_harness,flowaction,corr,listview) but no other rule types."
and you are correct, this matches up with the set of rules that are still managed outside of vtable.
I suspect that Rajiv was also correct in this comment: Re: pr_assembledclasses to vtable, I suspect that you only have generated code for a small subset of the actual rulebase.
Can you tell me about the lifecycle for the system database under test?
How was it installed?
What was imported?
How big is your total rulebase?
- Run SQL: select count(*) from pr_assembledclasses, select count(*) from pr4_rule* (for each of the tables prefixed by "pr4_rule")
- if you can get specific counts for each unique pr_assembledclasses.pzclass prefix (where pzclass like "ra_action_%.class", "ra_activity_%.class", etc) that would be awesome. That will tell us exactly what has been generated.
How are you "warming up" the system to ensure that all rules are called (and therefore generated) before running the test? ... or are you using any utility/tool to "pre-generate" rules?
Rulesware LLC
CA
Hi Bill,
I think I haven't been clear about our needs. Yes you are right, the generated code is where it has always been, In pr_assembledclasses.
However, I am also after the compiled class files (java byte code) , this is needed to calculate code coverage statistics.
I can force the compiled code into pr_assembledclasses using <env name="initialization/nofua/vtable/enable" value="false"/> ,
but I can only do that to validate that the vtables are in fact holding the compiled byte code.
I can't modify the prconfig.xml files in our functional and regression testing environments, because they have to be exactly the same as what goes out to our production systems.
What I really need is a vtable api (or better yet jdbc driver), so that I can retrieve the compiled code for each generated source code entry found in pr_assembledclasses .
Updated: 22 Mar 2016 9:21 EDT
Rulesware LLC
CA
I ran the following , on a clean install, where we loaded our application and just navigated through a few screens.
select pzjar, pzpackage, count(*) from pr_assembledclasses group by pzjar, pzpackage order by pzpackage, pzjar;
PZJAR | PZPACKAGE | COUNT(*) |
---|---|---|
prgenclasses.jar | com/pegarules/generated/activity | 400 |
prgenjava.jar | com/pegarules/generated/activity | 383 |
As you can see, we got a matching class file for each java source. However, the code coverage still comes up as 0% unless <env name="initialization/nofua/vtable/enable" value="false"/> is added to the prconfig.xml file. This tells me that the byte code in pr_assembledclasses and the byte code executed by the jvm are not the same. The code being executed by the jvm must be coming from the vtables. This is quite the puzzle.
Now earlier (1 month ago), there were many fewer class files than source files.
It may be that some recent hotfix has changed that behavior. I don't know for sure, but that is the behavior that I observed.
Also, you wanted to know if we are "warming up" the system. I do not think we are doing anything to preload the code base.
Rulesware LLC
CA
I ran the following , on a clean install, where a loaded our application and just navigated through a few screens.
select pzjar, pzpackage, count(*) from pr_assembledclasses group by pzjar, pzpackage order by pzpackage, pzjar;
PZJAR | PZPACKAGE | COUNT(*) |
---|---|---|
prgenclasses.jar | com/pegarules/generated/activity | 400 |
prgenjava.jar | com/pegarules/generated/activity | 383 |
As you can see, we got a matching class file for each java source. However, the code coverage still comes up as 0% unless <env name="initialization/nofua/vtable/enable" value="false"/> is added to the prconfig.xml file. This tells me that the byte code in pr_assembledclasses and the byte code executed by the jvm are not the same. The code being executed by the jvm must be coming from the vtables. This is quite the puzzle.
Now earlier (1 month ago), there were many fewer class files than source files.
It may be that some recent hotfix has changed that behavior. I don't know for sure, but that is the behavior that I observed.
Also, you wanted to know if we are "warming up" the system. I do not think we are doing anything to preload the code base.
Rulesware LLC
CA
Hello, so far we have only been able to get code coverage statistics using the following setting <env name="initialization/nofua/vtable/enable" value="false"/> in the prconfig.xml file.
It seems that the compiled class files (the ones actually executed by the jvm) are in the vtables. We need a way to access the contents of the vtables.
Pegasystems Inc.
US
Hello Joseph
Thanks for the interesting discussion! and for doing the queries.
We can see that the assembled classes for activities (& all other vtable rule types) are in the assembled classes table. That table is always used for the assembled classes. So Pega 7 is reading/loading those activity .class files from that table. However, for vtable rule types we do some byte code rewriting ourselves. I wonder if the code coverage tool that you use is effected by that.
What code coverage tool are you using? I suspect it also does byte code rewriting. Maybe they are interacting in some negative fashion
You could try this as a test. Please do not do this to your production or other important systems! But if you have a test system that you can play with. Try this
- shutdown the system
- truncate the pr_assembledclasses table
- add this to your prconfig.xml
- set "initialization/nofua/vtable/invokedynamic" to false
- Startup the system & try to do your code coverage.
See if that makes any difference
Thanks
Rulesware LLC
CA
Thank you Todd.
We are using Jacoco to perform the code coverage analysis , it would make a great addition to the PRPC suite of tools !
I'll try your suggested steps in the next couple days, and update you.
Thanks
Rulesware LLC
CA
Hello Todd,
Using that setting in prconfig.xml seems to have worked. The code coverage statistics look correct.
What would be our next steps?
Accepted Solution
Pegasystems Inc.
US
Hello Joseph
how are you? Thanks for the reply!
We do use Jacoco internally in Pega Engineering in some areas. Most developers use Eclipse here so we use EclEmma primarily for coverage analysis during product development. We also us Jacoco in automated CI & dev pipeline runs.
I've not heard of this problem. Likely because we are not using jacoco on our generated - assembled code. Instead, we use it on the product code
I highly suspect that our byte code rewriting in the product is somehow conflicting with (i assume likely...) bytecode rewriting by Jacoco. So it seems you could not use both our features related to "initialization/nofua/vtable/invokedynamic" & jacoco at the same time. The configuration setting for "initialization/nofua/vtable/invokedynamic" is used to disable a performance optimization related to When rules being called from other rules
As far as next steps. you could consider
Hello Joseph
how are you? Thanks for the reply!
We do use Jacoco internally in Pega Engineering in some areas. Most developers use Eclipse here so we use EclEmma primarily for coverage analysis during product development. We also us Jacoco in automated CI & dev pipeline runs.
I've not heard of this problem. Likely because we are not using jacoco on our generated - assembled code. Instead, we use it on the product code
I highly suspect that our byte code rewriting in the product is somehow conflicting with (i assume likely...) bytecode rewriting by Jacoco. So it seems you could not use both our features related to "initialization/nofua/vtable/invokedynamic" & jacoco at the same time. The configuration setting for "initialization/nofua/vtable/invokedynamic" is used to disable a performance optimization related to When rules being called from other rules
As far as next steps. you could consider
- If your code coverage needs are separate from your production performance requirements, you could considering using "initialization/nofua/vtable/invokedynamic" = false in your test environment with jacoco & "initialization/nofua/vtable/invokedynamic" = true in your other QA, UAT, & production environments.
I assume the purpose of jacoco coverage is to ensure your test suites exercise a realistic percentage of the assembled code. The amount of code exercised by your test cases would not vary depending upon the setting of "initialization/nofua/vtable/invokedynamic".
Hope this helps you
Thanks
Rulesware LLC
CA
I'll start a discussion with the nightly build people. Our problem is that the environment in testing is supposed to be identical to what will go to production. If the testing environment has a different prpc configuration, there is a chance that behavior in production will be incorrect, but correct in testing or vice versa.