ref = it.next();
+ next = ref.get();
+ if (next != null) {
+ return true;
}
+ it.remove();
+ }
+ return false;
+ }
- @Override
- public PackWriter next() {
- if (hasNext()) {
- PackWriter result = next;
- next = null;
- return result;
- }
- throw new NoSuchElementException();
- }
+ @Override
+ public PackWriter next() {
+ if (hasNext()) {
+ PackWriter result = next;
+ next = null;
+ return result;
+ }
+ throw new NoSuchElementException();
+ }
- @Override
- public void remove() {
- throw new UnsupportedOperationException();
- }
- };
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException();
}
};
@@ -1579,8 +1578,8 @@ public class PackWriter implements AutoCloseable {
if (pool.awaitTermination(60, TimeUnit.SECONDS))
break;
} catch (InterruptedException e) {
- throw new IOException(
- JGitText.get().packingCancelledDuringObjectsWriting);
+ throw new IOException(JGitText
+ .get().packingCancelledDuringObjectsWriting, e);
}
}
}
@@ -1604,7 +1603,8 @@ public class PackWriter implements AutoCloseable {
// Cross our fingers and just break out anyway.
//
throw new IOException(
- JGitText.get().packingCancelledDuringObjectsWriting);
+ JGitText.get().packingCancelledDuringObjectsWriting,
+ ie);
}
}
@@ -1645,7 +1645,7 @@ public class PackWriter implements AutoCloseable {
for (Future> f : futures)
f.cancel(true);
throw new IOException(
- JGitText.get().packingCancelledDuringObjectsWriting);
+ JGitText.get().packingCancelledDuringObjectsWriting, ie);
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/submodule/SubmoduleValidator.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/submodule/SubmoduleValidator.java
index 20066bec7..d0e24413b 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/submodule/SubmoduleValidator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/submodule/SubmoduleValidator.java
@@ -165,9 +165,10 @@ public class SubmoduleValidator {
}
}
} catch (ConfigInvalidException e) {
- throw new SubmoduleValidationException(
- JGitText.get().invalidGitModules,
- GITMODULES_PARSE);
+ SubmoduleValidationException sve = new SubmoduleValidationException(
+ JGitText.get().invalidGitModules, GITMODULES_PARSE);
+ sve.initCause(e);
+ throw sve;
}
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbreviatedObjectId.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbreviatedObjectId.java
index a5e4d787f..dc5e5cc20 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbreviatedObjectId.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/AbbreviatedObjectId.java
@@ -114,8 +114,11 @@ public final class AbbreviatedObjectId implements Serializable {
final int d = hexUInt32(bs, ptr + 24, end);
final int e = hexUInt32(bs, ptr + 32, end);
return new AbbreviatedObjectId(end - ptr, a, b, c, d, e);
- } catch (ArrayIndexOutOfBoundsException e1) {
- throw new InvalidObjectIdException(bs, ptr, end - ptr);
+ } catch (ArrayIndexOutOfBoundsException e) {
+ InvalidObjectIdException e1 = new InvalidObjectIdException(bs, ptr,
+ end - ptr);
+ e1.initCause(e);
+ throw e1;
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
index d502274c4..ffc742d47 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Constants.java
@@ -601,7 +601,10 @@ public final class Constants {
throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType);
}
} catch (ArrayIndexOutOfBoundsException bad) {
- throw new CorruptObjectException(id, JGitText.get().corruptObjectInvalidType);
+ CorruptObjectException coe = new CorruptObjectException(id,
+ JGitText.get().corruptObjectInvalidType);
+ coe.initCause(bad);
+ throw coe;
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java
index abc9b2119..cc0b995f1 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/DefaultTypedConfigGetter.java
@@ -46,7 +46,7 @@ public class DefaultTypedConfigGetter implements TypedConfigGetter {
return StringUtils.toBoolean(n);
} catch (IllegalArgumentException err) {
throw new IllegalArgumentException(MessageFormat.format(
- JGitText.get().invalidBooleanValue, section, name, n));
+ JGitText.get().invalidBooleanValue, section, name, n), err);
}
}
@@ -152,7 +152,8 @@ public class DefaultTypedConfigGetter implements TypedConfigGetter {
return mul * Long.parseLong(n);
} catch (NumberFormatException nfe) {
throw new IllegalArgumentException(MessageFormat.format(
- JGitText.get().invalidIntegerValue, section, name, str));
+ JGitText.get().invalidIntegerValue, section, name, str),
+ nfe);
}
}
@@ -239,7 +240,10 @@ public class DefaultTypedConfigGetter implements TypedConfigGetter {
return wantUnit.convert(Long.parseLong(digits) * inputMul,
inputUnit);
} catch (NumberFormatException nfe) {
- throw notTimeUnit(section, subsection, unitName, valueString);
+ IllegalArgumentException iae = notTimeUnit(section, subsection,
+ unitName, valueString);
+ iae.initCause(nfe);
+ throw iae;
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/MutableObjectId.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/MutableObjectId.java
index 86b306d5b..4a712ba36 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/MutableObjectId.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/MutableObjectId.java
@@ -234,9 +234,11 @@ public class MutableObjectId extends AnyObjectId {
w3 = RawParseUtils.parseHexInt32(bs, p + 16);
w4 = RawParseUtils.parseHexInt32(bs, p + 24);
w5 = RawParseUtils.parseHexInt32(bs, p + 32);
- } catch (ArrayIndexOutOfBoundsException e1) {
- throw new InvalidObjectIdException(bs, p,
+ } catch (ArrayIndexOutOfBoundsException e) {
+ InvalidObjectIdException e1 = new InvalidObjectIdException(bs, p,
Constants.OBJECT_ID_STRING_LENGTH);
+ e1.initCause(e);
+ throw e1;
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectId.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectId.java
index 11c0aefe3..269049f4a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectId.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectId.java
@@ -213,9 +213,11 @@ public class ObjectId extends AnyObjectId implements Serializable {
final int d = RawParseUtils.parseHexInt32(bs, p + 24);
final int e = RawParseUtils.parseHexInt32(bs, p + 32);
return new ObjectId(a, b, c, d, e);
- } catch (ArrayIndexOutOfBoundsException e1) {
- throw new InvalidObjectIdException(bs, p,
+ } catch (ArrayIndexOutOfBoundsException e) {
+ InvalidObjectIdException e1 = new InvalidObjectIdException(bs, p,
Constants.OBJECT_ID_STRING_LENGTH);
+ e1.initCause(e);
+ throw e1;
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
index 503e218b5..a7a832c1a 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/Repository.java
@@ -550,9 +550,11 @@ public abstract class Repository implements AutoCloseable {
try {
pnum = Integer.parseInt(parentnum);
} catch (NumberFormatException e) {
- throw new RevisionSyntaxException(
+ RevisionSyntaxException rse = new RevisionSyntaxException(
JGitText.get().invalidCommitParentNumber,
revstr);
+ rse.initCause(e);
+ throw rse;
}
if (pnum != 0) {
RevCommit commit = (RevCommit) rev;
@@ -647,8 +649,10 @@ public abstract class Repository implements AutoCloseable {
try {
dist = Integer.parseInt(distnum);
} catch (NumberFormatException e) {
- throw new RevisionSyntaxException(
+ RevisionSyntaxException rse = new RevisionSyntaxException(
JGitText.get().invalidAncestryLength, revstr);
+ rse.initCause(e);
+ throw rse;
}
} else
dist = 1;
@@ -707,7 +711,10 @@ public abstract class Repository implements AutoCloseable {
remoteConfig = new RemoteConfig(getConfig(),
"origin"); //$NON-NLS-1$
} catch (URISyntaxException e) {
- throw new RevisionSyntaxException(revstr);
+ RevisionSyntaxException rse = new RevisionSyntaxException(
+ revstr);
+ rse.initCause(e);
+ throw rse;
}
String remoteBranchName = getConfig()
.getString(
@@ -874,8 +881,11 @@ public abstract class Repository implements AutoCloseable {
try {
number = Integer.parseInt(time);
} catch (NumberFormatException nfe) {
- throw new RevisionSyntaxException(MessageFormat.format(
- JGitText.get().invalidReflogRevision, time));
+ RevisionSyntaxException rse = new RevisionSyntaxException(
+ MessageFormat.format(JGitText.get().invalidReflogRevision,
+ time));
+ rse.initCause(nfe);
+ throw rse;
}
assert number >= 0;
ReflogReader reader = getReflogReader(ref.getName());
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java
index a177c290e..9210ec172 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/AmazonS3.java
@@ -33,6 +33,7 @@ import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
+import java.util.Comparator;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
@@ -44,6 +45,8 @@ import java.util.Set;
import java.util.SortedMap;
import java.util.TimeZone;
import java.util.TreeMap;
+import java.util.stream.Collectors;
+import java.time.Instant;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
@@ -288,6 +291,8 @@ public class AmazonS3 {
*
* This method is primarily meant for obtaining a "recursive directory
* listing" rooted under the specified bucket and prefix location.
+ * It returns the keys sorted in reverse order of LastModified time
+ * (freshest keys first).
*
* @param bucket
* name of the bucket whose objects should be listed.
@@ -311,7 +316,10 @@ public class AmazonS3 {
do {
lp.list();
} while (lp.truncated);
- return lp.entries;
+
+ Comparator comparator = Comparator.comparingLong(KeyInfo::getLastModifiedSecs);
+ return lp.entries.stream().sorted(comparator.reversed())
+ .map(KeyInfo::getName).collect(Collectors.toList());
}
/**
@@ -620,8 +628,26 @@ public class AmazonS3 {
return p;
}
+ /**
+ * KeyInfo enables sorting of keys by lastModified time
+ */
+ private static final class KeyInfo {
+ private final String name;
+ private final long lastModifiedSecs;
+ public KeyInfo(String aname, long lsecs) {
+ name = aname;
+ lastModifiedSecs = lsecs;
+ }
+ public String getName() {
+ return name;
+ }
+ public long getLastModifiedSecs() {
+ return lastModifiedSecs;
+ }
+ }
+
private final class ListParser extends DefaultHandler {
- final List entries = new ArrayList<>();
+ final List entries = new ArrayList<>();
private final String bucket;
@@ -630,6 +656,8 @@ public class AmazonS3 {
boolean truncated;
private StringBuilder data;
+ private String keyName;
+ private Instant keyLastModified;
ListParser(String bn, String p) {
bucket = bn;
@@ -641,7 +669,7 @@ public class AmazonS3 {
if (prefix.length() > 0)
args.put("prefix", prefix); //$NON-NLS-1$
if (!entries.isEmpty())
- args.put("marker", prefix + entries.get(entries.size() - 1)); //$NON-NLS-1$
+ args.put("marker", prefix + entries.get(entries.size() - 1).getName()); //$NON-NLS-1$
for (int curAttempt = 0; curAttempt < maxAttempts; curAttempt++) {
final HttpURLConnection c = open("GET", bucket, "", args); //$NON-NLS-1$ //$NON-NLS-2$
@@ -650,12 +678,15 @@ public class AmazonS3 {
case HttpURLConnection.HTTP_OK:
truncated = false;
data = null;
+ keyName = null;
+ keyLastModified = null;
final XMLReader xr;
try {
xr = XMLReaderFactory.createXMLReader();
} catch (SAXException e) {
- throw new IOException(JGitText.get().noXMLParserAvailable);
+ throw new IOException(
+ JGitText.get().noXMLParserAvailable, e);
}
xr.setContentHandler(this);
try (InputStream in = c.getInputStream()) {
@@ -682,8 +713,13 @@ public class AmazonS3 {
public void startElement(final String uri, final String name,
final String qName, final Attributes attributes)
throws SAXException {
- if ("Key".equals(name) || "IsTruncated".equals(name)) //$NON-NLS-1$ //$NON-NLS-2$
+ if ("Key".equals(name) || "IsTruncated".equals(name) || "LastModified".equals(name)) { //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
data = new StringBuilder();
+ }
+ if ("Contents".equals(name)) { //$NON-NLS-1$
+ keyName = null;
+ keyLastModified = null;
+ }
}
@Override
@@ -703,10 +739,16 @@ public class AmazonS3 {
@Override
public void endElement(final String uri, final String name,
final String qName) throws SAXException {
- if ("Key".equals(name)) //$NON-NLS-1$
- entries.add(data.toString().substring(prefix.length()));
- else if ("IsTruncated".equals(name)) //$NON-NLS-1$
+ if ("Key".equals(name)) { //$NON-NLS-1$
+ keyName = data.toString().substring(prefix.length());
+ } else if ("IsTruncated".equals(name)) { //$NON-NLS-1$
truncated = StringUtils.equalsIgnoreCase("true", data.toString()); //$NON-NLS-1$
+ } else if ("LastModified".equals(name)) { //$NON-NLS-1$
+ keyLastModified = Instant.parse(data.toString());
+ } else if ("Contents".equals(name)) { //$NON-NLS-1$
+ entries.add(new KeyInfo(keyName, keyLastModified.getEpochSecond()));
+ }
+
data = null;
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java
index 8604244db..1417faee8 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/BasePackConnection.java
@@ -203,7 +203,9 @@ abstract class BasePackConnection extends BaseConnection {
try {
id = ObjectId.fromString(line.substring(0, 40));
} catch (InvalidObjectIdException e) {
- throw invalidRefAdvertisementLine(line);
+ PackProtocolException ppe = invalidRefAdvertisementLine(line);
+ ppe.initCause(e);
+ throw ppe;
}
if (name.equals(".have")) { //$NON-NLS-1$
additionalHaves.add(id);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/DefaultSshSessionFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/DefaultSshSessionFactory.java
index 063fb6b8b..afa0a11c2 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/DefaultSshSessionFactory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/DefaultSshSessionFactory.java
@@ -24,8 +24,10 @@ import com.jcraft.jsch.Session;
*
* If user interactivity is required by SSH (e.g. to obtain a password), the
* connection will immediately fail.
+ *
+ * @since 5.7
*/
-class DefaultSshSessionFactory extends JschConfigSessionFactory {
+public class DefaultSshSessionFactory extends JschConfigSessionFactory {
/** {@inheritDoc} */
@Override
protected void configure(OpenSshConfig.Host hc, Session session) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java
index 93800d500..c992bb1cb 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/PacketLineIn.java
@@ -286,7 +286,7 @@ public class PacketLineIn {
try {
len = RawParseUtils.parseHexInt16(lineBuffer, 0);
} catch (ArrayIndexOutOfBoundsException err) {
- throw invalidHeader();
+ throw invalidHeader(err);
}
if (len == 0) {
@@ -320,6 +320,12 @@ public class PacketLineIn {
+ (char) lineBuffer[2] + (char) lineBuffer[3]));
}
+ private IOException invalidHeader(Throwable cause) {
+ IOException ioe = invalidHeader();
+ ioe.initCause(cause);
+ return ioe;
+ }
+
/**
* IOException thrown by read when the configured input limit is exceeded.
*
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
index 8ca09f8ad..e505e1706 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/ReceivePack.java
@@ -1725,15 +1725,17 @@ public class ReceivePack {
* desired status to filter by.
* @return a copy of the command list containing only those commands with
* the desired status.
+ * @since 5.7
*/
- private List filterCommands(Result want) {
+ protected List filterCommands(Result want) {
return ReceiveCommand.filter(commands, want);
}
/**
* Execute commands to update references.
+ * @since 5.7
*/
- private void executeCommands() {
+ protected void executeCommands() {
List toApply = filterCommands(Result.NOT_ATTEMPTED);
if (toApply.isEmpty())
return;
@@ -2108,7 +2110,7 @@ public class ReceivePack {
} catch (InputOverLimitIOException e) {
String msg = JGitText.get().tooManyCommands;
fatalError(msg);
- throw new PackProtocolException(msg);
+ throw new PackProtocolException(msg, e);
} finally {
try {
close();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java
index 906c4ed2d..e6d204242 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/SshSessionFactory.java
@@ -13,6 +13,8 @@ package org.eclipse.jgit.transport;
import java.security.AccessController;
import java.security.PrivilegedAction;
+import java.util.Iterator;
+import java.util.ServiceLoader;
import org.eclipse.jgit.errors.TransportException;
import org.eclipse.jgit.lib.Constants;
@@ -31,8 +33,16 @@ import org.eclipse.jgit.util.SystemReader;
* SshSessionFactory for the duration of the period they are using the Session.
*/
public abstract class SshSessionFactory {
- private static SshSessionFactory INSTANCE = new DefaultSshSessionFactory();
+ private static SshSessionFactory INSTANCE = loadSshSessionFactory();
+ private static SshSessionFactory loadSshSessionFactory() {
+ ServiceLoader loader = ServiceLoader.load(SshSessionFactory.class);
+ Iterator iter = loader.iterator();
+ if(iter.hasNext()) {
+ return iter.next();
+ }
+ return null;
+ }
/**
* Get the currently configured JVM-wide factory.
*
@@ -53,10 +63,11 @@ public abstract class SshSessionFactory {
* default factory will be restored.s
*/
public static void setInstance(SshSessionFactory newFactory) {
- if (newFactory != null)
+ if (newFactory != null) {
INSTANCE = newFactory;
- else
- INSTANCE = new DefaultSshSessionFactory();
+ } else {
+ INSTANCE = loadSshSessionFactory();
+ }
}
/**
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TestProtocol.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TestProtocol.java
index 13b891fcf..c6ecb3a79 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TestProtocol.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TestProtocol.java
@@ -140,7 +140,7 @@ public class TestProtocol extends TransportProtocol {
int n = handles.size();
uri = new URIish(SCHEME + "://test/conn" + n); //$NON-NLS-1$
} catch (URISyntaxException e) {
- throw new IllegalStateException();
+ throw new IllegalStateException(e);
}
handles.put(uri, new Handle(req, remote));
return uri;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java
index 94f36d285..784f56615 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportAmazonS3.java
@@ -23,6 +23,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@@ -241,11 +242,14 @@ public class TransportAmazonS3 extends HttpTransport implements WalkTransport {
@Override
Collection getPackNames() throws IOException {
+ // s3.list returns most recently modified packs first.
+ // These are the packs most likely to contain missing refs.
+ final List packList = s3.list(bucket, resolveKey("pack")); //$NON-NLS-1$
final HashSet have = new HashSet<>();
- have.addAll(s3.list(bucket, resolveKey("pack"))); //$NON-NLS-1$
+ have.addAll(packList);
final Collection packs = new ArrayList<>();
- for (String n : have) {
+ for (String n : packList) {
if (!n.startsWith("pack-") || !n.endsWith(".pack")) //$NON-NLS-1$ //$NON-NLS-2$
continue;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleFile.java
index 155c115f8..04ebddb10 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleFile.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportBundleFile.java
@@ -113,7 +113,10 @@ class TransportBundleFile extends Transport implements TransportBundle {
try {
src = new FileInputStream(bundle);
} catch (FileNotFoundException err) {
- throw new TransportException(uri, JGitText.get().notFound);
+ TransportException te = new TransportException(uri,
+ JGitText.get().notFound);
+ te.initCause(err);
+ throw te;
}
return new BundleFetchConnection(this, src);
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java
index be17b44d7..403f98d86 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/TransportLocal.java
@@ -143,7 +143,10 @@ class TransportLocal extends Transport implements PackTransport {
.setFS(local != null ? local.getFS() : FS.DETECTED)
.setGitDir(remoteGitDir).build();
} catch (IOException err) {
- throw new TransportException(uri, JGitText.get().notAGitDirectory);
+ TransportException te = new TransportException(uri,
+ JGitText.get().notAGitDirectory);
+ te.initCause(err);
+ throw te;
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java
index 6ebb668c7..858d1f7b6 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java
@@ -266,7 +266,10 @@ public class URIish implements Serializable {
try {
val = parseHexByte(c1, c2);
} catch (ArrayIndexOutOfBoundsException e) {
- throw new URISyntaxException(s, JGitText.get().cannotParseGitURIish);
+ URISyntaxException use = new URISyntaxException(s,
+ JGitText.get().cannotParseGitURIish);
+ use.initCause(e);
+ throw use;
}
os[j++] = (byte) val;
i += 2;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java
index 1880c8b73..df9f11ecf 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/WalkEncryption.java
@@ -282,9 +282,12 @@ abstract class WalkEncryption {
String REGEX_TRANS = "(.+)/(.+)/(.+)"; //$NON-NLS-1$
}
- static GeneralSecurityException securityError(String message) {
- return new GeneralSecurityException(
+ static GeneralSecurityException securityError(String message,
+ Throwable cause) {
+ GeneralSecurityException e = new GeneralSecurityException(
MessageFormat.format(JGitText.get().encryptionError, message));
+ e.initCause(cause);
+ return e;
}
/**
@@ -332,21 +335,21 @@ abstract class WalkEncryption {
try {
size = Integer.parseInt(keySize);
} catch (Exception e) {
- throw securityError(X_KEY_SIZE + EMPTY + keySize);
+ throw securityError(X_KEY_SIZE + EMPTY + keySize, e);
}
final int iter;
try {
iter = Integer.parseInt(keyIter);
} catch (Exception e) {
- throw securityError(X_KEY_ITER + EMPTY + keyIter);
+ throw securityError(X_KEY_ITER + EMPTY + keyIter, e);
}
final byte[] salt;
try {
salt = Hex.decode(keySalt.replaceAll(REGEX_WS, EMPTY));
} catch (Exception e) {
- throw securityError(X_KEY_SALT + EMPTY + keySalt);
+ throw securityError(X_KEY_SALT + EMPTY + keySalt, e);
}
KeySpec keySpec = new PBEKeySpec(pass.toCharArray(), salt, iter, size);
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
index 02ca86b95..2c3f3e254 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/treewalk/WorkingTreeIterator.java
@@ -1159,7 +1159,7 @@ public abstract class WorkingTreeIterator extends AbstractTreeIterator {
} catch (CharacterCodingException e) {
// This should so never happen.
throw new RuntimeException(MessageFormat.format(
- JGitText.get().unencodeableFile, getName()));
+ JGitText.get().unencodeableFile, getName()), e);
}
encodedNameLen = b.limit();
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
index cd6647c62..415631805 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FS.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, Shawn O. Pearce and others
+ * Copyright (C) 2008, 2020 Shawn O. Pearce and others
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Distribution License v. 1.0 which is available at
@@ -49,11 +49,15 @@ import java.util.concurrent.CancellationException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.SynchronousQueue;
+import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -200,27 +204,52 @@ public abstract class FS {
public static final FileStoreAttributes FALLBACK_FILESTORE_ATTRIBUTES = new FileStoreAttributes(
FALLBACK_TIMESTAMP_RESOLUTION);
+ private static final String JAVA_VERSION_PREFIX = SystemReader
+ .getInstance().getHostname() + '|'
+ + System.getProperty("java.vendor") + '|' //$NON-NLS-1$
+ + System.getProperty("java.version") + '|'; //$NON-NLS-1$
+
+ private static final Duration FALLBACK_MIN_RACY_INTERVAL = Duration
+ .ofMillis(10);
+
private static final Map attributeCache = new ConcurrentHashMap<>();
private static final SimpleLruCache attrCacheByPath = new SimpleLruCache<>(
100, 0.2f);
- private static AtomicBoolean background = new AtomicBoolean();
+ private static final AtomicBoolean background = new AtomicBoolean();
+
+ private static final Map locks = new ConcurrentHashMap<>();
- private static Map locks = new ConcurrentHashMap<>();
+ private static final AtomicInteger threadNumber = new AtomicInteger(1);
+
+ /**
+ * Don't use the default thread factory of the ForkJoinPool for the
+ * CompletableFuture; it runs without any privileges, which causes
+ * trouble if a SecurityManager is present.
+ *
+ * Instead use normal daemon threads. They'll belong to the
+ * SecurityManager's thread group, or use the one of the calling thread,
+ * as appropriate.
+ *
+ *
+ * @see java.util.concurrent.Executors#newCachedThreadPool()
+ */
+ private static final Executor FUTURE_RUNNER = new ThreadPoolExecutor(0,
+ 5, 30L, TimeUnit.SECONDS, new SynchronousQueue(),
+ runnable -> {
+ Thread t = new Thread(runnable, "FileStoreAttributeReader-" //$NON-NLS-1$
+ + threadNumber.getAndIncrement());
+ // Make sure these threads don't prevent application/JVM
+ // shutdown.
+ t.setDaemon(true);
+ return t;
+ });
private static void setBackground(boolean async) {
background.set(async);
}
- private static final String javaVersionPrefix = SystemReader
- .getInstance().getHostname() + '|'
- + System.getProperty("java.vendor") + '|' //$NON-NLS-1$
- + System.getProperty("java.version") + '|'; //$NON-NLS-1$
-
- private static final Duration FALLBACK_MIN_RACY_INTERVAL = Duration
- .ofMillis(10);
-
/**
* Configures size and purge factor of the path-based cache for file
* system attributes. Caching of file system attributes avoids recurring
@@ -304,8 +333,7 @@ public abstract class FS {
// Some earlier future might have set the value
// and removed itself since we checked for the
// value above. Hence check cache again.
- FileStoreAttributes c = attributeCache
- .get(s);
+ FileStoreAttributes c = attributeCache.get(s);
if (c != null) {
return Optional.of(c);
}
@@ -339,7 +367,7 @@ public abstract class FS {
locks.remove(s);
}
return attributes;
- });
+ }, FUTURE_RUNNER);
f = f.exceptionally(e -> {
LOG.error(e.getLocalizedMessage(), e);
return Optional.empty();
@@ -450,6 +478,11 @@ public abstract class FS {
LOG.debug("{}: end measure timestamp resolution {} in {}", //$NON-NLS-1$
Thread.currentThread(), s, dir);
return Optional.of(fsResolution);
+ } catch (SecurityException e) {
+ // Log it here; most likely deleteProbe() below will also run
+ // into a SecurityException, and then this one will be lost
+ // without trace.
+ LOG.warn(e.getLocalizedMessage(), e);
} catch (AccessDeniedException e) {
LOG.warn(e.getLocalizedMessage(), e); // see bug 548648
} catch (IOException e) {
@@ -595,7 +628,7 @@ public abstract class FS {
} else {
storeKey = s.name();
}
- return javaVersionPrefix + storeKey;
+ return JAVA_VERSION_PREFIX + storeKey;
}
private static TimeUnit getUnit(long nanos) {
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
index fa99087fe..4831fbb64 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/FileUtils.java
@@ -300,7 +300,8 @@ public class FileUtils {
} catch (InterruptedException e) {
throw new IOException(
MessageFormat.format(JGitText.get().renameFileFailed,
- src.getAbsolutePath(), dst.getAbsolutePath()));
+ src.getAbsolutePath(), dst.getAbsolutePath()),
+ e);
}
}
throw new IOException(
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutInputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutInputStream.java
index 135613600..1947b3bf0 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutInputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutInputStream.java
@@ -70,7 +70,7 @@ public class TimeoutInputStream extends FilterInputStream {
beginRead();
return super.read();
} catch (InterruptedIOException e) {
- throw readTimedOut();
+ throw readTimedOut(e);
} finally {
endRead();
}
@@ -89,7 +89,7 @@ public class TimeoutInputStream extends FilterInputStream {
beginRead();
return super.read(buf, off, cnt);
} catch (InterruptedIOException e) {
- throw readTimedOut();
+ throw readTimedOut(e);
} finally {
endRead();
}
@@ -102,7 +102,7 @@ public class TimeoutInputStream extends FilterInputStream {
beginRead();
return super.skip(cnt);
} catch (InterruptedIOException e) {
- throw readTimedOut();
+ throw readTimedOut(e);
} finally {
endRead();
}
@@ -116,8 +116,11 @@ public class TimeoutInputStream extends FilterInputStream {
myTimer.end();
}
- private InterruptedIOException readTimedOut() {
- return new InterruptedIOException(MessageFormat.format(
- JGitText.get().readTimedOut, Integer.valueOf(timeout)));
+ private InterruptedIOException readTimedOut(InterruptedIOException e) {
+ InterruptedIOException interrupted = new InterruptedIOException(
+ MessageFormat.format(JGitText.get().readTimedOut,
+ Integer.valueOf(timeout)));
+ interrupted.initCause(e);
+ return interrupted;
}
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutOutputStream.java b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutOutputStream.java
index 7532c42b9..3fbf6ffdc 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutOutputStream.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/util/io/TimeoutOutputStream.java
@@ -72,7 +72,7 @@ public class TimeoutOutputStream extends OutputStream {
beginWrite();
dst.write(b);
} catch (InterruptedIOException e) {
- throw writeTimedOut();
+ throw writeTimedOut(e);
} finally {
endWrite();
}
@@ -91,7 +91,7 @@ public class TimeoutOutputStream extends OutputStream {
beginWrite();
dst.write(buf, off, len);
} catch (InterruptedIOException e) {
- throw writeTimedOut();
+ throw writeTimedOut(e);
} finally {
endWrite();
}
@@ -104,7 +104,7 @@ public class TimeoutOutputStream extends OutputStream {
beginWrite();
dst.flush();
} catch (InterruptedIOException e) {
- throw writeTimedOut();
+ throw writeTimedOut(e);
} finally {
endWrite();
}
@@ -117,7 +117,7 @@ public class TimeoutOutputStream extends OutputStream {
beginWrite();
dst.close();
} catch (InterruptedIOException e) {
- throw writeTimedOut();
+ throw writeTimedOut(e);
} finally {
endWrite();
}
@@ -131,8 +131,11 @@ public class TimeoutOutputStream extends OutputStream {
myTimer.end();
}
- private InterruptedIOException writeTimedOut() {
- return new InterruptedIOException(MessageFormat.format(
- JGitText.get().writeTimedOut, Integer.valueOf(timeout)));
+ private InterruptedIOException writeTimedOut(InterruptedIOException cause) {
+ InterruptedIOException e = new InterruptedIOException(
+ MessageFormat.format(JGitText.get().writeTimedOut,
+ Integer.valueOf(timeout)));
+ e.initCause(cause);
+ return e;
}
}
diff --git a/pom.xml b/pom.xml
index 2eeda672d..d0a5c83a1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -155,27 +155,27 @@
2.2.0
0.1.55
1.1.1
- 1.1.6
- 4.12
+ 1.1.7
+ 4.13
1C
2.33
- 1.18
+ 1.19
4.3.1
3.1.0
9.4.25.v20191220
- 0.14.1
- 4.5.6
- 4.4.10
+ 0.14.3
+ 4.5.10
+ 4.4.12
1.7.2
1.2.15
3.1.1
- 1.5.1
+ 1.6.0
2.8.2
1.64
3.1.12.2
3.0.0
3.0.0
- 3.0.0-M3
+ 3.0.0-M4
${maven-surefire-plugin-version}
3.8.1
@@ -298,7 +298,7 @@
org.apache.maven.plugins
maven-pmd-plugin
- 3.12.0
+ 3.13.0
utf-8
100
@@ -775,6 +775,11 @@
${bouncycastle-version}