This service will be undergoing maintenance at 00:00 UTC, 2017-10-23 It is expected to last about 30 minutes
Bug 827624 - ClassCastException when fetching a package from Guvnor
ClassCastException when fetching a package from Guvnor
Status: VERIFIED
Product: JBoss Enterprise BRMS Platform 5
Classification: JBoss
Component: BRM (Guvnor) (Show other bugs)
BRMS 5.3.0.GA
x86_64 Linux
unspecified Severity urgent
: ER9
: BRMS 5.3.0.GA
Assigned To: manstis
Sona Mala
:
Depends On:
Blocks:
  Show dependency treegraph
 
Reported: 2012-06-01 17:32 EDT by Hao Wu
Modified: 2012-06-19 10:59 EDT (History)
6 users (show)

See Also:
Fixed In Version:
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Environment:
Last Closed:
Type: Bug
Regression: ---
Mount Type: ---
Documentation: ---
CRM:
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---


Attachments (Terms of Use)
The pkg file of the package snapshot (2.49 KB, application/octet-stream)
2012-06-02 23:07 EDT, Hao Wu
no flags Details

  None (edit)
Description Hao Wu 2012-06-01 17:32:41 EDT
Description of problem:
Using a simple test:
        @Test
        public void testDownloadPkg () throws Exception {
            String s = "http://localhost:8080/jboss-brms/org.drools.guvnor.Guvnor/package/TestPkg/snap";
            KnowledgePackage pkg = new KnowledgePackageImp(new HttpClientImpl().fetchPackage(new URL(s), true, "admin", "admin"));
        }

Got exception:
        java.lang.ClassCastException: [Lorg.drools.rule.Package; cannot be cast to org.drools.rule.Package
            at org.drools.agent.HttpClientImpl.fetchPackage(HttpClientImpl.java:82)
            at test.redhat.test.TestDownloadPkg.testDownloadPkg(TestDownloadPkg.java:15)
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            at java.lang.reflect.Method.invoke(Method.java:601)
            at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
            at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
            at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
            at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
            at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
            at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
            at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
            at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
            at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
            at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
            at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
            at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
            at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
            at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
            at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

Using classes in:
drools-core-5.3.0.BRMS-ER8.jar

Version-Release number of selected component (if applicable):
ER8

How reproducible:


Steps to Reproduce:
    1. Create a new package in Guvnor
    2. Create a new DRL rule and put something generic like
        when
        then
            System.out.println("test");
    3. Build and create a snapshot
    4. Run test
    5. Got exception
  
Actual results:
Exception show above

Expected results:
Download package successfully


Additional info:
Comment 1 Hao Wu 2012-06-02 23:07:50 EDT
Created attachment 588769 [details]
The pkg file of the package snapshot
Comment 2 Prakash Aradhya 2012-06-07 10:47:44 EDT
This is a customer bug and needs to be a blocker...
Comment 3 Geoffrey De Smet 2012-06-12 10:57:57 EDT
Michael,

I 've reproduced the issue in a unit test on master:
  https://github.com/droolsjbpm/guvnor/commit/e5a710e75fd37c5fea617d140487a023b6318699

Hao,

Normally, users/customers shouldn't use internal classes like HttpClientImpl and KnowledgePackageImp. They have no backwards compatibility guarantees.
Have you tried using the normal api in the knowledge-api module to fetch that KnowledgePackage? I am not sure which classes to use exactly, but Mark or Edson should know.
Comment 4 Geoffrey De Smet 2012-06-12 11:02:44 EDT
The bug is that the o on this line is an array of Package, instead of a Package:
  return (Package) o;

The L on this line signifies that actually:
[Lorg.drools.rule.Package; cannot be cast to org.drools.rule.Package
Comment 5 Mark Proctor 2012-06-12 11:28:51 EDT
HttpClassImpl is very old and only meant for the old RuleAgent class, which was deprecated some time ago. As a result it seems fixes made to KnowledgeAgentImpl to handle alternative serialised formats where not apply to HttpClassImpl. We will be removing legacy classes very soon, so I don't think we should fix this.

My first question though is why not use the KnowlegeAgent directly, rather than doing this sort of thing manually.

Anyway if you wish to continue doing manual serialisation, I would recommend using the ResourceFactory and then rip the relevant helper method from KnowledgeAgentImpl. I haven't checked that this compiles, but it shows you the idea:

private Collection<KnowledgePackage> createPackageFromResource(Resource resource)       
    InputStream is = null;
    Collection<KnowledgePackage> kpkgs = null;
    try {
        is = resource.getInputStream();
        Object object = DroolsStreamUtils.streamIn( is );
        if ( object instanceof Collection ) {
            kpkgs = (Collection<KnowledgePackage>) object;
        } else if ( object instanceof KnowledgePackageImp ) {
            kpkgs = Collections.singletonList( (KnowledgePackage) object );
        } else if( object instanceof Package ) {
            kpkgs = Collections.singletonList( (KnowledgePackage) new KnowledgePackageImp( (Package) object ) );
        } else if( object instanceof Package[] ) {
            kpkgs = new ArrayList<KnowledgePackage>();
            for( Package pkg : (Package[]) object ) {
                kpkgs.add( new KnowledgePackageImp( pkg ) );
            }
        } else {
            throw new RuntimeException("Unknown binary format trying to load resource "+resource.toString());
        }
    } catch ( Exception ex ) {
        this.listener.exception( new RuntimeException( "KnowledgeAgent exception while trying to deserialize KnowledgeDefinitionsPackage  ",
                                                       ex ) );
    } finally {
        try {
            if ( is != null ) {
                is.close();
            }
        } catch ( IOException e ) {
            this.listener.exception( new RuntimeException( "KnowledgeAgent exception while trying to close KnowledgeDefinitionsPackage  ",
                                                           e ) );
        }
    }
}
Comment 6 Mark Proctor 2012-06-12 11:46:57 EDT
I would add that RuleAgent at the moment is completely brocken. That this is the first time a problem has occured, is a good thing, it means no one has used it until now. And it is considered deprecated.

We can fix RuleAgent and related classes. But it involves changing method signatures and lots of instanceofs. Should we do this for a deprecated class, if this is the first customer who has a problem, and they now have a work around anyway?
Comment 7 Geoffrey De Smet 2012-06-12 11:55:36 EDT
Here's the code to build the Resource parameter in Mark's post from an URL:

        Resource res = ResourceFactory.newUrlResource(url);
        KnowledgeAgentConfiguration conf = KnowledgeAgentFactory.newKnowledgeAgentConfiguration();
        Authenticator.setDefault(new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication("admin", "admin".toCharArray());
            }
        });
Comment 8 manstis 2012-06-12 15:24:36 EDT
Recommendation is to move to use of KnowledgeAgent or use code based on KnowledgeAgentImpl (comment #5). No further action required by engineering.
Comment 9 Ryan Zhang 2012-06-13 05:32:53 EDT
This issue's fixes  have been picked by ER9. Please verify them on ER9.
Comment 10 Sona Mala 2012-06-19 10:59:16 EDT
Workaround is verified for ER9. 
The code of workaround:
  - the body of testDownloadPkg is comment #7
  - testDownloadPkg calls createPackageFromResource (comment #5)

Note You need to log in before you can comment on or make changes to this bug.