[ https://issues.apache.org/jira/browse/SLING-3737?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14052603#comment-14052603 ]
Ian Boston commented on SLING-3737: ----------------------------------- I am +1 on applying this patch, although since I didn't write the code I think Stefan should check it an merge. He has far more experience with Topology. > Instance Sling Identifier may be randomly reset on restart > ---------------------------------------------------------- > > Key: SLING-3737 > URL: https://issues.apache.org/jira/browse/SLING-3737 > Project: Sling > Issue Type: Bug > Components: Extensions > Affects Versions: Settings 1.3.0 > Reporter: Timothee Maret > > In our Setup, we experience instances which change their Sling identifier > upon restart. > We experiences only a few occurrences of this issue, but the effect is really > bad, turing the services relying on the Sling Identifier into un expected > state (for instance Sling discovery service). > We have checked that the sling.id.file was present before the issue occurred. > We also checked that the value in this file was valid (36 byte long UUID). > Despite this valid file, the instance reset the Sling ID. > Looking at the latest code in > org.apache.sling.settings.impl.SlingSettingsServiceImpl#readSlingId > it seems there is a bug in the way the sling.id.file file is read. > {code} > private String readSlingId(final File idFile) { > if (idFile.exists() && idFile.length() >= 36) { > FileInputStream fin = null; > try { > fin = new FileInputStream(idFile); > final byte[] rawBytes = new byte[36]; > if (fin.read(rawBytes) == 36) { > final String rawString = new String(rawBytes, > "ISO-8859-1"); > // roundtrip to ensure correct format of UUID value > final String id = UUID.fromString(rawString).toString(); > logger.debug("Got Sling ID {} from file {}", id, idFile); > return id; > } > } catch (final Throwable t) { > logger.error("Failed reading UUID from id file " + idFile > + ", creating new id", t); > } finally { > if (fin != null) { > try { > fin.close(); > } catch (IOException ignore) { > } > } > } > } > return null; > } > {code} > In the line > {code} > if (fin.read(rawBytes) == 36) { > {code} > The code miss uses the java.io.FileInputStream#read API. > {code} > /** > * Reads up to <code>b.length</code> bytes of data from this input > * stream into an array of bytes. This method blocks until some input > * is available. > * > * @param b the buffer into which the data is read. > * @return the total number of bytes read into the buffer, or > * <code>-1</code> if there is no more data because the end of > * the file has been reached. > * @exception IOException if an I/O error occurs. > */ > {code} > The API stipulates that the method blocks until if finds *some* data. > This is a common pattern with Java IO APIs, and indeed, the method may return > with only one byte read even though the end of the stream was not reached. > If this is the case, the current logic will treat the slingId as invalid and > generate a new one. > A way to fix that is to read the sling id file completely, for instance using > the org.apache.commons.io.FileUtils API > We are running on CentOS 6.2, JDK 1.7. -- This message was sent by Atlassian JIRA (v6.2#6252)