[jbossts-issues] [JBoss JIRA] (JBTM-2189) Bootstrapping from Complex Classloader (OneJar)

Mark Little (JIRA) issues at jboss.org
Tue Jun 10 13:03:15 EDT 2014


    [ https://issues.jboss.org/browse/JBTM-2189?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12974990#comment-12974990 ] 

Mark Little commented on JBTM-2189:
-----------------------------------

For clarity in future if others come to this issue, can you please describe what problem you've seen and hence why you've submitted a patch. Thanks.

> Bootstrapping from Complex Classloader (OneJar)
> -----------------------------------------------
>
>                 Key: JBTM-2189
>                 URL: https://issues.jboss.org/browse/JBTM-2189
>             Project: JBoss Transaction Manager
>          Issue Type: Feature Request
>      Security Level: Public(Everyone can see) 
>          Components: Common
>    Affects Versions: 5.0.1
>         Environment: JDK 8, OneJar 0.97
>            Reporter: Chris Pheby
>            Assignee: Tom Jenkinson
>
> I am using Narayana within a JavaSE application. The application is compiled into a single Jar. When executing, Narayana fails to bootstrap properly.
> The first problem is within com.arjuna.common.util.ConfigurationInfo.
> Lines 111-115 aim to load the MANIFEST file from the classpath:
>         String pathToManifest = basePath+"/META-INF/MANIFEST.MF";
>         InputStream is = null;
>         try {
>             is = new URL(pathToManifest).openStream();
> I replaced this with:
>         InputStream is = null;
>         // BEGIN - WORKAROUND FOR ONE-JAR
>         try {
>         	String targetPrefix = pathToThisClass.substring(0, pathToThisClass.length() - "/com/arjuna/common/util/ConfigurationInfo.class".length());
>             Enumeration<URL> resources = ConfigurationInfo.class.getClassLoader().getResources("META-INF/MANIFEST.MF");
>             while (resources.hasMoreElements()) {
>             	URL next = resources.nextElement();
>             	if (next.toString().startsWith(targetPrefix)) {
>             		is = next.openStream();
>             		break;
>             	}
>             }        	
>         // END - WORKAROUND FOR ONE-JAR
> This should work for all environments.
> Changes are also required in com.arjuna.common.util.propertyservice.AbstractPropertiesFactory to attempt loading from classpath as well as file system:
> The last line of initDefaultProperties (195) needed changing to:
>         defaultProperties = getPropertiesFromClasspath(propertyFileName, PropertiesFactoryStax.class.getClassLoader());
>         if (defaultProperties == null) {
>         	defaultProperties = getPropertiesFromFile(propertyFileName, PropertiesFactoryStax.class.getClassLoader()); 
>         }
>     }
> and the following methods added / replaced:
>     /**
>      * Returns the config properties read from a specified relative location on the classpath.
>      *
>      * @param propertyFileName the file name relative to the classpath root. 
>      * @return the Properties loaded from the specified source.
>      */
>     public Properties getPropertiesFromClasspath(String propertyFileName, ClassLoader classLoader) {
>     	Properties properties = null;
>     	
>     	try {
>             Enumeration<URL> resources = ConfigurationInfo.class.getClassLoader().getResources(propertyFileName);
>             while (resources.hasMoreElements()) {
>             	URL next = resources.nextElement();
>             	
>             	properties = loadFromStream(next.openStream());
>             	return properties;
>             }        	
>         } catch(Exception e) {
>             return null;
>         }
>         return properties;
>     }
>     
>     /**
>      * Returns the config properties read from a specified location.
>      *
>      * @param propertyFileName the file name. If relative, this is located using the FileLocator algorithm.
>      * @return the Properties loaded from the specified source.
>      */
>     public Properties getPropertiesFromFile(String propertyFileName, ClassLoader classLoader) {
>         String propertiesSourceUri = null;
>         try
>         {
>             // This is the point where the search path is applied - user.dir (pwd), user.home, java.home, classpath
>             propertiesSourceUri = com.arjuna.common.util.propertyservice.FileLocator.locateFile(propertyFileName, classLoader);
>         }
>         catch(FileNotFoundException fileNotFoundException)
>         {
>             // try falling back to a default file built into the .jar
>             // Note the default- prefix on the name, to avoid finding it from the .jar at the previous stage
>             // in cases where the .jar comes before the etc dir on the classpath.
>             URL url = AbstractPropertiesFactory.class.getResource("/default-"+propertyFileName);
>             if(url == null) {
>                 throw new RuntimeException("missing property file "+propertyFileName);
>             } else {
>                 propertiesSourceUri = url.toString();
>             }
>         }
>         catch (IOException e)
>         {
>             throw new RuntimeException("invalid property file "+propertiesSourceUri, e);
>         }
>         Properties properties = null;
>         try {
>             properties = loadFromFile(propertiesSourceUri);
>             properties = applySystemProperties(properties);
>         } catch(Exception e) {
>             throw new RuntimeException("unable to load properties from "+propertiesSourceUri, e);
>         }
>         return properties;
>     }
>     private Properties loadFromStream(InputStream inputStream) throws IOException {
>     	Properties inputProperties = new Properties();
>         Properties outputProperties = new Properties();
>         try {
>             loadFromXML(inputProperties,inputStream);
>         } finally {
>             inputStream.close();
>         }
>         Enumeration namesEnumeration = inputProperties.propertyNames();
>         while(namesEnumeration.hasMoreElements()) {
>             String propertyName = (String)namesEnumeration.nextElement();
>             String propertyValue = inputProperties.getProperty(propertyName);
>             propertyValue = propertyValue.trim();
>             // perform JBossAS style property substitutions. JBTM-369
>             propertyValue = StringPropertyReplacer.replaceProperties(propertyValue);
>             outputProperties.setProperty(propertyName, propertyValue);
>         }
>         return outputProperties;
>     }



--
This message was sent by Atlassian JIRA
(v6.2.3#6260)


More information about the jbossts-issues mailing list