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

Tom Jenkinson (JIRA) issues at jboss.org
Wed Jun 11 07:43:39 EDT 2014


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

Tom Jenkinson commented on JBTM-2189:
-------------------------------------

Hi Chris,

Many thanks for your interest in Narayana. Normally for something like this it is best to start with a discussion on our forums over here: https://community.jboss.org/en/jbosstm. That said, please can you add a little more detail into the description as to the nature of the bug. We do already function in Java SE and also complex classloader hierarchies so this may be a corner case which we would be happy to work with you to address. I am not familiar with OneJar, is it a maven plugin that will put all the dependency jar classes into the same Jar as the application jar? The main problem with your report as it stands is that we don't have a well defined reason for _why_ the change needs to be made, if you can express the motivation for the change in more general terms then we can get it merged. As you say, the fix looks like it should work in our currently supported options so it shouldn't be a problem to get it merged once we have more context to backup the need to merge it.

Once we understand the problem better, and we proceed with your approach, please can you:
1. Sign the CLA over here: https://cla.jboss.org/ (project is JBoss Transactions)
2. Fork: https://github.com/jbosstm/narayana
3. Raise a pull request on the main repo with your fix in. It should be easier to review inline, plus it will get CI run on it.

Many thanks for the contribution!
Tom

> 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.6#6264)


More information about the jbossts-issues mailing list