Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 355087

Summary: Issue with external bindings file with package-name and given in a map
Product: z_Archived Reporter: Denise Smith <denise.mahar>
Component: EclipselinkAssignee: David McCann <david.mccann>
Status: RESOLVED FIXED QA Contact:
Severity: normal    
Priority: P2 CC: blaise.doughan, david.mccann, david.twelves
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: Windows 7   
Whiteboard:
Attachments:
Description Flags
Proposed fix.
none
Supporting test case.
none
Supporting test case. none

Description Denise Smith CLA 2011-08-18 09:57:38 EDT
A JAXBContext can be created fine with this properties map:
   InputStream is = ClassLoader.getSystemResourceAsStream("test/oxm.xml");
   Map<String, InputStream> properties = new HashMap<String, InputStream>();
   properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, inputStream);

Now if I put the bindings into a map keyed on package I get an exception
   InputStream is= ClassLoader.getSystemResourceAsStream("test/oxm.xml");
   Map<String, Map<String, Source>> props = new HashMap<String, Map<String, Source>>();
   HashMap<String, Source> metadataSourceMap = new HashMap<String, Source>();
   metadataSourceMap.put("test", new StreamSource(inputStream));
   props.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, metadataSourceMap);

The bindings file has a package-name specified and unqualified class names
<?xml version="1.0" encoding="US-ASCII"?>
<xml-bindings xmlns="somthing" package-name="test">
    <java-types>
        <java-type name="CustomQuoteRequest">
            <xml-root-element name="QuoteRequest"/>
            <java-attributes>

  
This is the exception that occurs with the properties given as a map
junit.framework.AssertionFailedError: Exception in constructor: testMappings (Local Exception Stack:
Exception [EclipseLink-50025] (Eclipse Persistence Services - @VERSION@.@QUALIFIER@): org.eclipse.persistence.exceptions.JAXBException
Exception Description: Could not load class [CustomQuoteRequest] declared in the external metadata file.  Please ensure that the class name is correct, and that the correct ClassLoader has been set.
    at org.eclipse.persistence.exceptions.JAXBException.couldNotLoadClassFromMetadata(JAXBException.java:373)
    at org.eclipse.persistence.jaxb.JAXBContext$TypeMappingInfoInput.getXmlBindingsClasses(JAXBContext.java:975)
    at org.eclipse.persistence.jaxb.JAXBContext$TypeMappingInfoInput.createContextState(JAXBContext.java:877)
    at org.eclipse.persistence.jaxb.JAXBContext.<init>(JAXBContext.java:140)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:142)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:129)
    at org.eclipse.persistence.jaxb.JAXBContextFactory.createContext(JAXBContextFactory.java:93)
    at org.eclipse.persistence.testing.jaxb.JAXBTestCases.setClasses(JAXBTestCases.java:126)
    at org.eclipse.persistence.testing.jaxb.externalizedmetadata.mappings.multiple.MultipleMappingPerFieldTestCases.<init>(MultipleMappingPerFieldTestCases.java:56)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at junit.framework.TestSuite.createTest(TestSuite.java:65)
    at junit.framework.TestSuite.addTestMethod(TestSuite.java:283)
    at junit.framework.TestSuite.<init>(TestSuite.java:146)
    at org.junit.internal.runners.JUnit38ClassRunner.<init>(JUnit38ClassRunner.java:71)
    at org.junit.internal.builders.JUnit3Builder.runnerForClass(JUnit3Builder.java:14)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
    at org.junit.internal.builders.AllDefaultPossibilitiesBuilder.runnerForClass(AllDefaultPossibilitiesBuilder.java:29)
    at org.junit.runners.model.RunnerBuilder.safeRunnerForClass(RunnerBuilder.java:57)
    at org.junit.internal.requests.ClassRequest.getRunner(ClassRequest.java:24)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.<init>(JUnit4TestReference.java:32)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestClassReference.<init>(JUnit4TestClassReference.java:25)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.createTest(JUnit4TestLoader.java:41)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestLoader.loadTests(JUnit4TestLoader.java:31)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:452)
    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)
Comment 1 Denise Smith CLA 2011-08-18 14:30:01 EDT
To recreate go to test

org.eclipse.persistence.testing.jaxb.externalizedmetadata.mappings.multiple.MultipleMappingPerFieldTestCases

Change getProperties method to this
    
    public Map getProperties(){
    	
        InputStream inputStream = ClassLoader.getSystemResourceAsStream("org/eclipse/persistence/testing/jaxb/externalizedmetadata/mappings/multiple/oxm.xml");
        Map<String, Map<String, Source>> properties = new HashMap<String, Map<String, Source>>();
        HashMap<String, Source> metadataSourceMap = new HashMap<String, Source>();
        metadataSourceMap.put("org.eclipse.persistence.testing.jaxb.externalizedmetadata.mappings.multiple", new StreamSource(inputStream));
        properties.put(JAXBContextFactory.ECLIPSELINK_OXM_XML_KEY, metadataSourceMap);
        return properties;
Comment 2 David McCann CLA 2012-05-22 14:08:58 EDT
Created attachment 216062 [details]
Proposed fix.

We now do not modify non-fully qualified JavaType names.  

A convenience method was added to the JavaModel Helper class that will prepend a package name to a given java class name if it isn't already fully qualified.

In any spots where we attempt load classes by class name, we call into the above-montioned convenience method to ensure we perform the load with a fully qualified JavaType name.

For dynamic, we now need to make sure that a given JavaType name is fully qualified (existing code assumes this to be so) upon creation of an OXMJavaClassImpl instance.
Comment 3 David McCann CLA 2012-05-22 14:10:16 EDT
Created attachment 216063 [details]
Supporting test case.

Modified the tests based on the comments below to reproduce the issue and test the fix.
Comment 4 David McCann CLA 2012-05-22 15:54:56 EDT
Created attachment 216073 [details]
Supporting test case.

Added inner class to main test object to make sure we handle prepending the package name properly for inner classes as well.  Needed to mod the schema, metadata file and CustomQuoteRequest class.
Comment 5 David McCann CLA 2012-05-22 15:58:45 EDT
Reviewed by:  blaise.doughan@oracle.com 
Tests: MultipleMappingPerFieldTestCases; all MOXy unit tests pass as expected
Revision: 11453
Comment 6 Eclipse Webmaster CLA 2022-06-09 10:03:10 EDT
The Eclipselink project has moved to Github: https://github.com/eclipse-ee4j/eclipselink