Merge "Remove singleton for multiDexLegacy marker" into ub-jack
diff --git a/dx/src/com/android/jack/dx/dex/file/DexFile.java b/dx/src/com/android/jack/dx/dex/file/DexFile.java
index 5bc9cb6..916d5c8 100644
--- a/dx/src/com/android/jack/dx/dex/file/DexFile.java
+++ b/dx/src/com/android/jack/dx/dex/file/DexFile.java
@@ -23,6 +23,7 @@
import com.android.jack.dx.rop.cst.CstEnumRef;
import com.android.jack.dx.rop.cst.CstFieldRef;
import com.android.jack.dx.rop.cst.CstMethodRef;
+import com.android.jack.dx.rop.cst.CstPrototypeRef;
import com.android.jack.dx.rop.cst.CstString;
import com.android.jack.dx.rop.cst.CstType;
import com.android.jack.dx.util.ByteArrayAnnotatedOutput;
@@ -442,6 +443,8 @@
fieldIds.intern((CstFieldRef) cst);
} else if (cst instanceof CstEnumRef) {
fieldIds.intern(((CstEnumRef) cst).getFieldRef());
+ } else if (cst instanceof CstPrototypeRef) {
+ protoIds.intern(((CstPrototypeRef) cst).getPrototype());
} else if (cst == null) {
throw new NullPointerException("cst == null");
}
@@ -467,6 +470,8 @@
return methodIds.get(cst);
} else if (cst instanceof CstFieldRef) {
return fieldIds.get(cst);
+ } else if (cst instanceof CstPrototypeRef) {
+ return protoIds.get(cst);
} else {
return null;
}
diff --git a/dx/src/com/android/jack/dx/dex/file/ProtoIdsSection.java b/dx/src/com/android/jack/dx/dex/file/ProtoIdsSection.java
index 33cb976..4740173 100644
--- a/dx/src/com/android/jack/dx/dex/file/ProtoIdsSection.java
+++ b/dx/src/com/android/jack/dx/dex/file/ProtoIdsSection.java
@@ -17,6 +17,7 @@
package com.android.jack.dx.dex.file;
import com.android.jack.dx.rop.cst.Constant;
+import com.android.jack.dx.rop.cst.CstPrototypeRef;
import com.android.jack.dx.rop.type.Prototype;
import com.android.jack.dx.util.AnnotatedOutput;
import com.android.jack.dx.util.Hex;
@@ -24,6 +25,8 @@
import java.util.Collection;
import java.util.TreeMap;
+import javax.annotation.Nonnull;
+
/**
* Proto (method prototype) identifiers list section of a
* {@code .dex} file.
@@ -53,8 +56,14 @@
/** {@inheritDoc} */
@Override
- public IndexedItem get(Constant cst) {
- throw new UnsupportedOperationException("unsupported");
+ @Nonnull
+ public IndexedItem get(@Nonnull Constant cst) {
+ throwIfNotPrepared();
+
+ IndexedItem result = protoIds.get(((CstPrototypeRef) cst).getPrototype());
+ assert result != null;
+
+ return result;
}
/**
diff --git a/dx/src/com/android/jack/dx/io/IndexType.java b/dx/src/com/android/jack/dx/io/IndexType.java
index 515af59..7129597 100644
--- a/dx/src/com/android/jack/dx/io/IndexType.java
+++ b/dx/src/com/android/jack/dx/io/IndexType.java
@@ -41,6 +41,9 @@
/** field reference index */
FIELD_REF,
+ /** prototype reference index */
+ PROTOTYPE_REF,
+
/** inline method index (for inline linked method invocations) */
INLINE_METHOD,
diff --git a/dx/src/com/android/jack/dx/rop/cst/CstPrototypeRef.java b/dx/src/com/android/jack/dx/rop/cst/CstPrototypeRef.java
new file mode 100644
index 0000000..c954aac
--- /dev/null
+++ b/dx/src/com/android/jack/dx/rop/cst/CstPrototypeRef.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.jack.dx.rop.cst;
+
+import com.android.jack.dx.rop.type.Prototype;
+import com.android.jack.dx.rop.type.Type;
+
+import javax.annotation.Nonnull;
+
+/**
+ * Constants of type reference to a {@Link Prototype}.
+ */
+public final class CstPrototypeRef extends TypedConstant {
+
+ /** {@code non-null;} the reference prototype */
+ @Nonnull
+ private final Prototype prototype;
+
+ /**
+ * Constructs an instance from a {@link CstPrototypeRef}.
+ *
+ * @param prototype {@code non-null;} the referenced prototype
+ */
+ public CstPrototypeRef(@Nonnull Prototype prototype) {
+ assert prototype != null;
+ this.prototype = prototype;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public final boolean equals(@Nonnull Object other) {
+ if (!(other instanceof CstPrototypeRef)) {
+ return false;
+ }
+
+ return prototype.equals(((CstPrototypeRef) other).prototype);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public final int hashCode() {
+ return prototype.hashCode();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ protected int compareTo0(@Nonnull Constant other) {
+ return prototype.compareTo(((CstPrototypeRef) other).prototype);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Nonnull
+ public String toString() {
+ return typeName() + '{' + toHuman() + '}';
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Nonnull
+ public String typeName() {
+ return "prototype";
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean isCategory2() {
+ return false;
+ }
+
+ /**
+ * Gets the referenced prototype. This doesn't include a {@code this} argument.
+ *
+ * @return {@code non-null;} the referenced prototype
+ */
+ @Nonnull
+ public final Prototype getPrototype() {
+ return prototype;
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Nonnull
+ public Type getType() {
+ return prototype.getReturnType();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ @Nonnull
+ public String toHuman() {
+ return prototype.toString();
+ }
+}
diff --git a/jack-api/src/com/android/jack/api/ConfigNotSupportedAnymoreException.java b/jack-api/src/com/android/jack/api/ConfigNotSupportedAnymoreException.java
new file mode 100644
index 0000000..8cc6c16
--- /dev/null
+++ b/jack-api/src/com/android/jack/api/ConfigNotSupportedAnymoreException.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.jack.api;
+
+import javax.annotation.Nonnull;
+
+/**
+ * Thrown when the requested Jack configuration for a given API version is not supported because
+ * this Jack does not support this configuration anymore.
+ */
+public class ConfigNotSupportedAnymoreException extends ConfigNotSupportedException {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Construct the exception with no details.
+ */
+ public ConfigNotSupportedAnymoreException() {
+ super();
+ }
+
+ /**
+ * Construct the exception with a {@link String} message.
+ * @param message the message
+ */
+ public ConfigNotSupportedAnymoreException(@Nonnull String message) {
+ super(message);
+ }
+
+ /**
+ * Construct the exception with a {@link String} message and a {@link Throwable} cause.
+ * @param message the message
+ * @param cause the cause
+ */
+ public ConfigNotSupportedAnymoreException(@Nonnull String message, @Nonnull Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Construct the exception with a {@link Throwable} cause.
+ * @param cause the cause
+ */
+ public ConfigNotSupportedAnymoreException(@Nonnull Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/jack-api/src/com/android/jack/api/UnknownConfigException.java b/jack-api/src/com/android/jack/api/UnknownConfigException.java
new file mode 100644
index 0000000..1f6e028
--- /dev/null
+++ b/jack-api/src/com/android/jack/api/UnknownConfigException.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.jack.api;
+
+import javax.annotation.Nonnull;
+
+/**
+ * Thrown when the requested Jack configuration for a given API version is not supported because it
+ * is unknown to this Jack.
+ */
+public class UnknownConfigException extends ConfigNotSupportedException {
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Construct the exception with no details.
+ */
+ public UnknownConfigException() {
+ super();
+ }
+
+ /**
+ * Construct the exception with a {@link String} message.
+ * @param message the message
+ */
+ public UnknownConfigException(@Nonnull String message) {
+ super(message);
+ }
+
+ /**
+ * Construct the exception with a {@link String} message and a {@link Throwable} cause.
+ * @param message the message
+ * @param cause the cause
+ */
+ public UnknownConfigException(@Nonnull String message, @Nonnull Throwable cause) {
+ super(message, cause);
+ }
+
+ /**
+ * Construct the exception with a {@link Throwable} cause.
+ * @param cause the cause
+ */
+ public UnknownConfigException(@Nonnull Throwable cause) {
+ super(cause);
+ }
+}
diff --git a/jack-tests/prebuilts/core-stubs-mini.jack b/jack-tests/prebuilts/core-stubs-mini.jack
index 76a4383..f519179 100644
--- a/jack-tests/prebuilts/core-stubs-mini.jack
+++ b/jack-tests/prebuilts/core-stubs-mini.jack
Binary files differ
diff --git a/jack-tests/prebuilts/core-stubs-mini.jar b/jack-tests/prebuilts/core-stubs-mini.jar
index 114bfdc..99f6f63 100644
--- a/jack-tests/prebuilts/core-stubs-mini.jar
+++ b/jack-tests/prebuilts/core-stubs-mini.jar
Binary files differ
diff --git a/jack-tests/prebuilts/ecj-tests-lib.jar b/jack-tests/prebuilts/ecj-tests-lib.jar
index 49af442..e508f48 100644
--- a/jack-tests/prebuilts/ecj-tests-lib.jar
+++ b/jack-tests/prebuilts/ecj-tests-lib.jar
Binary files differ
diff --git a/jack-tests/prebuilts/junit4-lib.jack b/jack-tests/prebuilts/junit4-lib.jack
index 520459f..ad87d1f 100644
--- a/jack-tests/prebuilts/junit4-lib.jack
+++ b/jack-tests/prebuilts/junit4-lib.jack
Binary files differ
diff --git a/jack/prebuilts/core-stubs-mini.jack b/jack/prebuilts/core-stubs-mini.jack
index 76a4383..f519179 100644
--- a/jack/prebuilts/core-stubs-mini.jack
+++ b/jack/prebuilts/core-stubs-mini.jack
Binary files differ
diff --git a/jack/prebuilts/core-stubs-mini.jar b/jack/prebuilts/core-stubs-mini.jar
index 114bfdc..99f6f63 100644
--- a/jack/prebuilts/core-stubs-mini.jar
+++ b/jack/prebuilts/core-stubs-mini.jar
Binary files differ
diff --git a/jack/src/com/android/jack/api/impl/JackProviderImpl.java b/jack/src/com/android/jack/api/impl/JackProviderImpl.java
index fd08c4a..1192187 100644
--- a/jack/src/com/android/jack/api/impl/JackProviderImpl.java
+++ b/jack/src/com/android/jack/api/impl/JackProviderImpl.java
@@ -17,10 +17,12 @@
package com.android.jack.api.impl;
import com.android.jack.Jack;
+import com.android.jack.api.ConfigNotSupportedAnymoreException;
import com.android.jack.api.ConfigNotSupportedException;
import com.android.jack.api.JackConfig;
import com.android.jack.api.JackProvider;
import com.android.jack.api.ResourceController;
+import com.android.jack.api.UnknownConfigException;
import com.android.jack.api.v01.Api01Config;
import com.android.jack.api.v01.Cli01Config;
import com.android.jack.api.v01.impl.Api01Feature;
@@ -74,9 +76,13 @@
@Override
@SuppressWarnings("unchecked")
public <T extends JackConfig> T createConfig(Class<T> cls) throws ConfigNotSupportedException {
+ if (!impl.containsKey(cls)) {
+ throw new UnknownConfigException(cls.getName() + " is not supported");
+ }
+
Class<? extends JackConfigImpl> clsImpl = impl.get(cls);
if (clsImpl == null) {
- throw new ConfigNotSupportedException(cls.getName() + " is not supported");
+ throw new ConfigNotSupportedAnymoreException(cls.getName() + " is not supported anymore");
}
try {
diff --git a/jack/src/com/android/jack/backend/dex/ClassDefItemBuilder.java b/jack/src/com/android/jack/backend/dex/ClassDefItemBuilder.java
index f91a606..ce3d7ba 100644
--- a/jack/src/com/android/jack/backend/dex/ClassDefItemBuilder.java
+++ b/jack/src/com/android/jack/backend/dex/ClassDefItemBuilder.java
@@ -142,14 +142,16 @@
CstString sourceFile = null;
SourceInfo sourceInfo = type.getSourceInfo();
- // Only keep filename without the path
- String sourceFileName = sourceInfo.getFileName();
- String fileSeparator = FileUtils.getFileSeparator();
- int separatorPos = sourceFileName.lastIndexOf(fileSeparator);
- if (separatorPos > 0) {
- sourceFileName = sourceFileName.substring(separatorPos + 1);
+ if (sourceInfo != SourceInfo.UNKNOWN) {
+ // Only keep filename without the path
+ String sourceFileName = sourceInfo.getFileName();
+ String fileSeparator = FileUtils.getFileSeparator();
+ int separatorPos = sourceFileName.lastIndexOf(fileSeparator);
+ if (separatorPos > 0) {
+ sourceFileName = sourceFileName.substring(separatorPos + 1);
+ }
+ sourceFile = new CstString(sourceFileName);
}
- sourceFile = new CstString(sourceFileName);
return sourceFile;
}
diff --git a/jack/src/com/android/jack/ecj/loader/jast/JAstBinaryMethod.java b/jack/src/com/android/jack/ecj/loader/jast/JAstBinaryMethod.java
index bb486dd..262318e 100644
--- a/jack/src/com/android/jack/ecj/loader/jast/JAstBinaryMethod.java
+++ b/jack/src/com/android/jack/ecj/loader/jast/JAstBinaryMethod.java
@@ -32,6 +32,7 @@
import org.eclipse.jdt.internal.compiler.env.IBinaryAnnotation;
import org.eclipse.jdt.internal.compiler.env.IBinaryMethod;
import org.eclipse.jdt.internal.compiler.env.IBinaryTypeAnnotation;
+import org.eclipse.jdt.internal.compiler.lookup.TagBits;
import java.util.List;
@@ -218,6 +219,11 @@
@Override
public long getTagBits() {
long tagBits = AnnotationUtils.getTagBits(jMethod);
+
+ if (jMethod.hasPolymorphicSignature()) {
+ tagBits |= TagBits.AnnotationPolymorphicSignature;
+ }
+
return tagBits;
}
diff --git a/jack/src/com/android/jack/ir/ast/JMethod.java b/jack/src/com/android/jack/ir/ast/JMethod.java
index e131807..52769ce 100644
--- a/jack/src/com/android/jack/ir/ast/JMethod.java
+++ b/jack/src/com/android/jack/ir/ast/JMethod.java
@@ -18,11 +18,13 @@
import com.android.jack.Jack;
import com.android.jack.ir.JNodeInternalError;
+import com.android.jack.ir.formatter.UserFriendlyFormatter;
import com.android.jack.ir.sourceinfo.SourceInfo;
import com.android.jack.load.MethodLoader;
import com.android.jack.load.NopMethodLoader;
import com.android.jack.util.AnnotationUtils;
import com.android.jack.util.NamingTools;
+import com.android.jack.util.TriStateBoolean;
import com.android.sched.item.Component;
import com.android.sched.item.Description;
import com.android.sched.marker.Marker;
@@ -68,6 +70,9 @@
@Nonnull
private MethodLoader loader;
+ @Nonnull
+ TriStateBoolean hasPolymorphicSignature = TriStateBoolean.UNDEFINED;
+
public JMethod(@Nonnull SourceInfo info,
@Nonnull JMethodId methodId,
@Nonnull JDefinedClassOrInterface enclosingType,
@@ -116,6 +121,7 @@
assert JModifier.isMethodModifier(modifier);
assert JModifier.isValidMethodModifier(modifier);
this.modifier = modifier;
+ hasPolymorphicSignature = TriStateBoolean.UNDEFINED;
}
/**
@@ -123,6 +129,7 @@
*/
public void addParam(JParameter parameter) {
params.add(parameter);
+ hasPolymorphicSignature = TriStateBoolean.UNDEFINED;
}
/**
@@ -130,6 +137,7 @@
*/
public void prependParam(JParameter parameter) {
params.add(0, parameter);
+ hasPolymorphicSignature = TriStateBoolean.UNDEFINED;
}
/**
@@ -371,6 +379,8 @@
if (!transform(annotations, existingNode, (JAnnotation) newNode, transformation)) {
super.transform(existingNode, newNode, transformation);
}
+ } else {
+ hasPolymorphicSignature = TriStateBoolean.UNDEFINED;
}
}
@@ -465,4 +475,21 @@
return true;
}
+
+ public boolean hasPolymorphicSignature() {
+ if (hasPolymorphicSignature.isUndefined()) {
+ UserFriendlyFormatter formatter = UserFriendlyFormatter.getFormatter();
+
+ if (formatter.getName(getEnclosingType()).equals("java.lang.invoke.MethodHandle")
+ && (isVarags() && params.size() == 1
+ && formatter.getName(params.get(0).getType()).equals("java.lang.Object[]"))
+ && formatter.getName(getType()).equals("java.lang.Object") && isNative()) {
+ hasPolymorphicSignature = TriStateBoolean.TRUE;
+ } else {
+ hasPolymorphicSignature = TriStateBoolean.FALSE;
+ }
+ }
+
+ return hasPolymorphicSignature.isTrue();
+ }
}
diff --git a/jack/src/com/android/jack/ir/impl/JackIrBuilder.java b/jack/src/com/android/jack/ir/impl/JackIrBuilder.java
index 414c48c..609f606 100644
--- a/jack/src/com/android/jack/ir/impl/JackIrBuilder.java
+++ b/jack/src/com/android/jack/ir/impl/JackIrBuilder.java
@@ -2868,7 +2868,7 @@
((JMethodBody) body).getBlock().addStmt(
new JReturnStatement(session.getSourceInfoFactory().create(
method.getSourceInfo().getEndLine(), method.getSourceInfo().getEndLine(),
- method.getSourceInfo().getFileName()), null));
+ method.getSourceInfo()), null));
addAnnotations(x.annotations, curClass.type);
@@ -3842,7 +3842,7 @@
curMethod.body.getBlock().addStmt(new JReturnStatement(session.getSourceInfoFactory().create(
curMethod.method.getSourceInfo().getEndLine(),
curMethod.method.getSourceInfo().getEndLine(),
- curMethod.method.getSourceInfo().getFileName()), null));
+ curMethod.method.getSourceInfo()), null));
}
}
diff --git a/jack/src/com/android/jack/ir/sourceinfo/SourceInfo.java b/jack/src/com/android/jack/ir/sourceinfo/SourceInfo.java
index cee4c88..3dd22e9 100644
--- a/jack/src/com/android/jack/ir/sourceinfo/SourceInfo.java
+++ b/jack/src/com/android/jack/ir/sourceinfo/SourceInfo.java
@@ -19,6 +19,7 @@
import com.android.sched.util.location.FileLocation;
import com.android.sched.util.location.HasLocation;
import com.android.sched.util.location.Location;
+import com.android.sched.util.location.NoLocation;
import javax.annotation.Nonnull;
@@ -61,28 +62,30 @@
@Override
@Nonnull
public Location getLocation() {
- Location location;
- FileLocation fileLocation = new FileLocation(getFileName());
- if (getStartLine() != UNKNOWN_LINE_NUMBER) {
- int endLine = getEndLine();
- if (endLine == UNKNOWN_LINE_NUMBER) {
- endLine = ColumnAndLineLocation.UNKNOWN;
- }
+ Location location = NoLocation.getInstance();
+ if (this != SourceInfo.UNKNOWN) {
+ FileLocation fileLocation = new FileLocation(getFileName());
+ if (getStartLine() != UNKNOWN_LINE_NUMBER) {
+ int endLine = getEndLine();
+ if (endLine == UNKNOWN_LINE_NUMBER) {
+ endLine = ColumnAndLineLocation.UNKNOWN;
+ }
- int startColumn = getStartColumn();
- if (startColumn == UNKNOWN_LINE_NUMBER) {
- startColumn = ColumnAndLineLocation.UNKNOWN;
- }
+ int startColumn = getStartColumn();
+ if (startColumn == UNKNOWN_LINE_NUMBER) {
+ startColumn = ColumnAndLineLocation.UNKNOWN;
+ }
- int endColumn = getEndColumn();
- if (endColumn == UNKNOWN_LINE_NUMBER) {
- endColumn = ColumnAndLineLocation.UNKNOWN;
- }
+ int endColumn = getEndColumn();
+ if (endColumn == UNKNOWN_LINE_NUMBER) {
+ endColumn = ColumnAndLineLocation.UNKNOWN;
+ }
- location =
- new ColumnAndLineLocation(fileLocation, getStartLine(), endLine, startColumn, endColumn);
- } else {
- location = fileLocation;
+ location = new ColumnAndLineLocation(fileLocation, getStartLine(), endLine, startColumn,
+ endColumn);
+ } else {
+ location = fileLocation;
+ }
}
return location;
}
diff --git a/jack/src/com/android/jack/ir/sourceinfo/SourceInfoFactory.java b/jack/src/com/android/jack/ir/sourceinfo/SourceInfoFactory.java
index bff5df1..66b2042 100644
--- a/jack/src/com/android/jack/ir/sourceinfo/SourceInfoFactory.java
+++ b/jack/src/com/android/jack/ir/sourceinfo/SourceInfoFactory.java
@@ -49,6 +49,7 @@
*/
@Nonnull
public FileSourceInfo create(@Nonnull String fileName) {
+ assert fileName != null;
FileSourceInfo newInstance = canonicalFileSourceInfos.get(fileName);
if (newInstance == null) {
newInstance = new FileSourceInfo(fileName);
@@ -108,13 +109,19 @@
}
/**
- * Creates SourceInfo nodes. This factory method will provide
- * canonicalized instances of SourceInfo objects.
+ * Creates SourceInfo nodes with a file name coming from another SourceInfo. This factory method
+ * will provide canonicalized instances of SourceInfo objects.
*/
@Nonnull
- public LineSourceInfo create(
- @Nonnegative int startLine, @Nonnegative int endLine, @Nonnull FileSourceInfo fileName) {
- LineSourceInfo newInstance = new LineSourceInfo(fileName, startLine, endLine);
+ public SourceInfo create(@Nonnegative int startLine, @Nonnegative int endLine,
+ @Nonnull SourceInfo originalSourceInfo) {
+ if (originalSourceInfo == SourceInfo.UNKNOWN) {
+ assert startLine == SourceInfo.UNKNOWN_LINE_NUMBER;
+ assert endLine == SourceInfo.UNKNOWN_LINE_NUMBER;
+ return SourceInfo.UNKNOWN;
+ }
+ LineSourceInfo newInstance =
+ new LineSourceInfo(originalSourceInfo.getFileSourceInfo(), startLine, endLine);
LineSourceInfo canonical = canonicalLineSourceInfos.get(newInstance);
assert canonical == null || (newInstance != canonical && newInstance.equals(canonical));
diff --git a/jack/src/com/android/jack/ir/sourceinfo/UnknownSourceInfo.java b/jack/src/com/android/jack/ir/sourceinfo/UnknownSourceInfo.java
index 05c5f3c..c662a1a 100644
--- a/jack/src/com/android/jack/ir/sourceinfo/UnknownSourceInfo.java
+++ b/jack/src/com/android/jack/ir/sourceinfo/UnknownSourceInfo.java
@@ -22,10 +22,9 @@
/**
* Represents the source information when the origin of a node is unknown.
*/
-public class UnknownSourceInfo extends FileSourceInfo {
+public class UnknownSourceInfo extends SourceInfo {
UnknownSourceInfo() {
- super("Unknown");
}
@Override
@@ -33,4 +32,10 @@
public String toString() {
return "Unknown source info";
}
+
+ @Override
+ @Nonnull
+ public FileSourceInfo getFileSourceInfo() {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/jack/src/com/android/jack/jayce/v0004/Version.java b/jack/src/com/android/jack/jayce/v0004/Version.java
index 218179e..76296d3 100644
--- a/jack/src/com/android/jack/jayce/v0004/Version.java
+++ b/jack/src/com/android/jack/jayce/v0004/Version.java
@@ -21,7 +21,7 @@
*/
public class Version {
- public static final int MINOR_MIN = 0;
+ public static final int MINOR_MIN = 1;
- public static final int CURRENT_MINOR = 0;
+ public static final int CURRENT_MINOR = 1;
}
diff --git a/jack/src/com/android/jack/jayce/v0004/io/JayceInternalReaderImpl.java b/jack/src/com/android/jack/jayce/v0004/io/JayceInternalReaderImpl.java
index 10c4626..2f32759 100644
--- a/jack/src/com/android/jack/jayce/v0004/io/JayceInternalReaderImpl.java
+++ b/jack/src/com/android/jack/jayce/v0004/io/JayceInternalReaderImpl.java
@@ -109,6 +109,11 @@
public String readCurrentFileName() throws IOException {
if (tokenizer.readOpenFileName()) {
currentFileName = readString();
+ // UNKNOW_LINE_NUMBER is not dump for unknown debug information, reset it automatically.
+ // Current file name sets to null means unknown debug information.
+ if (currentFileName == null) {
+ currentLine = SourceInfo.UNKNOWN_LINE_NUMBER;
+ }
tokenizer.readCloseFileName();
}
return currentFileName;
@@ -206,8 +211,6 @@
return null;
}
-
-
tokenizer.readOpen();
NNode node;
try {
@@ -238,8 +241,10 @@
if (nodeLevel != NodeLevel.TYPES) {
if (node instanceof HasSourceInfo) {
+ fileName = readCurrentFileName();
int endLine = readCurrentLine();
- if (fileName == null && startLine == 0 && endLine == 0) {
+ if (fileName == null) {
+ assert startLine == 0 && endLine == 0;
((HasSourceInfo) node).setSourceInfos(SourceInfo.UNKNOWN);
} else {
assert fileName != null;
diff --git a/jack/src/com/android/jack/jayce/v0004/io/JayceInternalWriterImpl.java b/jack/src/com/android/jack/jayce/v0004/io/JayceInternalWriterImpl.java
index 79d52d7..645e246 100644
--- a/jack/src/com/android/jack/jayce/v0004/io/JayceInternalWriterImpl.java
+++ b/jack/src/com/android/jack/jayce/v0004/io/JayceInternalWriterImpl.java
@@ -92,15 +92,24 @@
private void writeSourceInfoBegin(@Nonnull NNode node) throws IOException {
if (node instanceof HasSourceInfo) {
SourceInfo sourceInfo = ((HasSourceInfo) node).getSourceInfos();
- writeFileNameIfDifferentFromCurrent(sourceInfo.getFileName());
- writeLineIfDifferentFromCurrent(sourceInfo.getStartLine());
+ if (sourceInfo == SourceInfo.UNKNOWN) {
+ writeUnknowDebug();
+ } else {
+ writeFileNameIfDifferentFromCurrent(sourceInfo.getFileName());
+ writeLineIfDifferentFromCurrent(sourceInfo.getStartLine());
+ }
}
}
private void writeSourceInfoEnd(@Nonnull NNode node) throws IOException {
if (node instanceof HasSourceInfo) {
- writeLineIfDifferentFromCurrent(
- ((HasSourceInfo) node).getSourceInfos().getEndLine());
+ SourceInfo sourceInfo = ((HasSourceInfo) node).getSourceInfos();
+ if (sourceInfo == SourceInfo.UNKNOWN) {
+ writeUnknowDebug();
+ } else {
+ writeFileNameIfDifferentFromCurrent(sourceInfo.getFileName());
+ writeLineIfDifferentFromCurrent(sourceInfo.getEndLine());
+ }
}
}
@@ -258,22 +267,30 @@
}
}
- public void writeCurrentFileName(@Nonnull String fileName) throws IOException {
+ private void writeUnknowDebug() throws IOException {
+ if (currentFileName != null) {
+ writeOpenFileName();
+ writeString(null);
+ writeCloseFileName();
+ currentFileName = null;
+ currentLineNumber = 0;
+ }
+ }
+
+ private void writeCurrentFileName(@CheckForNull String fileName) throws IOException {
writeOpenFileName();
writeString(fileName);
writeCloseFileName();
currentFileName = fileName;
}
- public void writeLineIfDifferentFromCurrent(@Nonnegative int lineNumber)
- throws IOException {
+ public void writeLineIfDifferentFromCurrent(@Nonnegative int lineNumber) throws IOException {
if (lineNumber != currentLineNumber) {
writeCurrentLine(lineNumber);
}
}
- public void writeCurrentLine(@Nonnegative int lineNumber)
- throws IOException {
+ public void writeCurrentLine(@Nonnegative int lineNumber) throws IOException {
writeOpenLineInfo();
writeTrimmedInt(lineNumber);
writeCloseLineInfo();
diff --git a/jack/src/com/android/jack/library/v0003/Version.java b/jack/src/com/android/jack/library/v0003/Version.java
index bf25c2a1..d4d843d 100644
--- a/jack/src/com/android/jack/library/v0003/Version.java
+++ b/jack/src/com/android/jack/library/v0003/Version.java
@@ -21,9 +21,9 @@
*/
public class Version {
- public static final int MINOR_MIN = 1;
+ public static final int MINOR_MIN = 2;
- public static final int MINOR = 1;
+ public static final int MINOR = 2;
public static final int MAJOR = 3;
}
diff --git a/jack/src/com/android/jack/shrob/shrink/KeepMarker.java b/jack/src/com/android/jack/shrob/shrink/KeepMarker.java
index 960dfab..1c6a193 100644
--- a/jack/src/com/android/jack/shrob/shrink/KeepMarker.java
+++ b/jack/src/com/android/jack/shrob/shrink/KeepMarker.java
@@ -31,12 +31,6 @@
@Description("Indicates that this class or member should not be removed when shrinking.")
public class KeepMarker extends BaseTracerMarker {
- @Nonnull
- public static final KeepMarker INSTANCE = new KeepMarker();
-
- private KeepMarker() {
- }
-
@DynamicValidOn
public boolean isValidOn(@Nonnull JDefinedClassOrInterface type) {
return type.isToEmit();
diff --git a/jack/src/com/android/jack/shrob/shrink/KeeperBrush.java b/jack/src/com/android/jack/shrob/shrink/KeeperBrush.java
index 8915f0c..84890ee 100644
--- a/jack/src/com/android/jack/shrob/shrink/KeeperBrush.java
+++ b/jack/src/com/android/jack/shrob/shrink/KeeperBrush.java
@@ -79,7 +79,7 @@
@Nonnull
@Override
protected KeepMarker createMarkerFor(@Nonnull JNode node) {
- return KeepMarker.INSTANCE;
+ return new KeepMarker();
}
@Override
diff --git a/jack/src/com/android/jack/transformations/ast/TryWithResourcesTransformer.java b/jack/src/com/android/jack/transformations/ast/TryWithResourcesTransformer.java
index 7bccea2..4ac6d7c 100644
--- a/jack/src/com/android/jack/transformations/ast/TryWithResourcesTransformer.java
+++ b/jack/src/com/android/jack/transformations/ast/TryWithResourcesTransformer.java
@@ -194,13 +194,11 @@
if (x.getResourcesDeclarations().size() > 0) {
SourceInfo trySourceInfo = x.getSourceInfo();
- SourceInfo endOfTrySourceInfos = sourceInfoFactory.create(
- trySourceInfo.getEndLine(), trySourceInfo.getEndLine(),
- trySourceInfo.getFileSourceInfo());
+ SourceInfo endOfTrySourceInfos = sourceInfoFactory.create(trySourceInfo.getEndLine(),
+ trySourceInfo.getEndLine(), trySourceInfo);
- SourceInfo firstLineSourceInfos = sourceInfoFactory.create(
- trySourceInfo.getStartLine(), trySourceInfo.getStartLine(),
- trySourceInfo.getFileSourceInfo());
+ SourceInfo firstLineSourceInfos = sourceInfoFactory.create(trySourceInfo.getStartLine(),
+ trySourceInfo.getStartLine(), trySourceInfo);
JBlock finalTryBlock = new JBlock(trySourceInfo);
diff --git a/jack/src/com/android/jack/util/TriStateBoolean.java b/jack/src/com/android/jack/util/TriStateBoolean.java
new file mode 100644
index 0000000..8e41166
--- /dev/null
+++ b/jack/src/com/android/jack/util/TriStateBoolean.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.jack.util;
+
+/**
+ * Boolean with three state.
+ */
+public enum TriStateBoolean {
+ UNDEFINED,
+ TRUE,
+ FALSE;
+
+ public boolean isTrue() {
+ return this == TRUE;
+ }
+
+ public boolean isFalse() {
+ return this == FALSE;
+ }
+
+ public boolean isUndefined() {
+ return this == UNDEFINED;
+ }
+}
diff --git a/jill/src/com/android/jill/frontend/java/JavaTransformer.java b/jill/src/com/android/jill/frontend/java/JavaTransformer.java
index b7d0cc8..27402a9 100644
--- a/jill/src/com/android/jill/frontend/java/JavaTransformer.java
+++ b/jill/src/com/android/jill/frontend/java/JavaTransformer.java
@@ -77,13 +77,13 @@
private static final String LIB_MAJOR_VERSION = "3";
@Nonnull
- private static final String LIB_MINOR_VERSION = "1";
+ private static final String LIB_MINOR_VERSION = "2";
@Nonnull
private static final String JAYCE_MAJOR_VERSION = "4";
@Nonnull
- private static final String JAYCE_MINOR_VERSION = "0";
+ private static final String JAYCE_MINOR_VERSION = "1";
@Nonnull
private static final String KEY_LIB_MAJOR_VERSION = "lib.version.major";
diff --git a/jill/src/com/android/jill/frontend/java/SourceInfoWriter.java b/jill/src/com/android/jill/frontend/java/SourceInfoWriter.java
index 9ef4f22..19b81d6 100644
--- a/jill/src/com/android/jill/frontend/java/SourceInfoWriter.java
+++ b/jill/src/com/android/jill/frontend/java/SourceInfoWriter.java
@@ -55,33 +55,26 @@
writeDebugBegin(cn, NO_LINE);
}
- public void writeDebugBegin(@Nonnull ClassNode cn, @Nonnull FieldNode fn)
- throws IOException {
+ public void writeDebugBegin(@Nonnull ClassNode cn, @Nonnull FieldNode fn) throws IOException {
writeUnknwonDebugBegin();
}
- public void writeDebugBegin(@Nonnull ClassNode cn, int startLine)
- throws IOException {
+ public void writeDebugBegin(@Nonnull ClassNode cn, int startLine) throws IOException {
if (cn.sourceFile == null) {
writeUnknwonDebugBegin();
} else {
- writeDebugBeginInternal(cn.sourceFile, startLine);
+ writeFileNameIfDifferentFromCurrent(cn.sourceFile);
+ writeLineIfDifferentFromCurrent(startLine);
}
}
public void writeUnknwonDebugBegin() throws IOException {
- writeDebugBeginInternal(NO_FILENAME, NO_LINE);
- }
-
- private void writeDebugBeginInternal(@CheckForNull String sourceFile, int startLine)
- throws IOException {
- writeFileNameIfDifferentFromCurrent(sourceFile);
- writeLineIfDifferentFromCurrent(startLine);
+ writeUnknowDebug();
}
public void writeDebugEnd(@Nonnull ClassNode cn)
throws IOException {
- writeUnknownDebugEnd();
+ writeDebugEnd(cn, NO_LINE);
}
public void writeDebugEnd(@Nonnull ClassNode cn, @Nonnull FieldNode fn)
@@ -91,32 +84,39 @@
public void writeDebugEnd(@Nonnull ClassNode cn, int endLine) throws IOException {
if (cn.sourceFile == null) {
- writeUnknownDebugEnd();
+ writeUnknwonDebugBegin();
} else {
+ writeFileNameIfDifferentFromCurrent(cn.sourceFile);
writeLineIfDifferentFromCurrent(endLine);
}
}
public void writeUnknownDebugEnd() throws IOException {
- writeLineIfDifferentFromCurrent(NO_LINE);
+ writeUnknowDebug();
}
- private void writeFileNameIfDifferentFromCurrent(@CheckForNull String fileName)
+ private void writeUnknowDebug() throws IOException {
+ if (currentFileName != null) {
+ writeCurrentFileName(null);
+ currentLineNumber = 0;
+ }
+ }
+
+ private void writeFileNameIfDifferentFromCurrent(@Nonnull String fileName)
throws IOException {
- if (fileName != null && !fileName.equals(currentFileName)) {
+ if (!fileName.equals(currentFileName)) {
writeCurrentFileName(fileName);
}
- // Assume that elements with unknown debug infos are in same file.
}
- private void writeCurrentFileName(@Nonnull String fileName)
+ private void writeCurrentFileName(@CheckForNull String fileName)
throws IOException {
writer.writeFileName(fileName);
currentFileName = fileName;
}
- private void writeLineIfDifferentFromCurrent(@Nonnegative int lineNumber)
- throws IOException {
+ private void writeLineIfDifferentFromCurrent(@Nonnegative int lineNumber) throws IOException {
+ assert currentFileName != NO_FILENAME || lineNumber == NO_LINE;
if (lineNumber != currentLineNumber) {
writeCurrentLine(lineNumber);
}
diff --git a/sched/src/com/android/sched/util/RunnableHooks.java b/sched/src/com/android/sched/util/RunnableHooks.java
index 07430fc..33a5cdb 100644
--- a/sched/src/com/android/sched/util/RunnableHooks.java
+++ b/sched/src/com/android/sched/util/RunnableHooks.java
@@ -21,9 +21,12 @@
import com.android.sched.util.config.HasKeyId;
import com.android.sched.util.config.ThreadConfig;
import com.android.sched.util.config.id.ObjectId;
+import com.android.sched.util.log.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javax.annotation.Nonnull;
@@ -37,6 +40,8 @@
@HasKeyId
public class RunnableHooks {
@Nonnull
+ private final Logger logger = LoggerFactory.getLogger();
+ @Nonnull
private static final ObjectId<RunnableHooks> SHUTDOWN_HOOKS =
new ObjectId<RunnableHooks>("sched.internal.shutdown", RunnableHooks.class);
@@ -56,11 +61,30 @@
}
public synchronized void runHooks() {
+ Throwable current = null;
+
for (Runnable hook : Lists.reverse(hooks)) {
- hook.run();
+ try {
+ hook.run();
+ } catch (Error | RuntimeException e) {
+ logger.log(Level.SEVERE, "Uncaught exception during RunnableHook", e);
+ if (current == null) {
+ // Throw only the first one
+ current = e;
+ }
+ }
}
hooks.clear();
+ if (current != null) {
+ if (current instanceof Error) {
+ throw (Error) current;
+ } else if (current instanceof RuntimeException) {
+ throw (RuntimeException) current;
+ } else {
+ throw new AssertionError(current);
+ }
+ }
}
/**
diff --git a/server/jack-server/src/com/android/jack/server/JackHttpServer.java b/server/jack-server/src/com/android/jack/server/JackHttpServer.java
index 2112a62..3534a4c 100644
--- a/server/jack-server/src/com/android/jack/server/JackHttpServer.java
+++ b/server/jack-server/src/com/android/jack/server/JackHttpServer.java
@@ -147,6 +147,9 @@
*/
public class JackHttpServer implements HasVersion {
+ @Nonnull
+ public static final String VERSION_CODE = "jack-server";
+
/**
* Define an assertion status.
*/
@@ -502,7 +505,7 @@
@Nonnull
public static Version getServerVersion() {
try {
- return new Version("jack-server", JackHttpServer.class.getClassLoader());
+ return new Version(VERSION_CODE, JackHttpServer.class.getClassLoader());
} catch (IOException e) {
logger.log(Level.SEVERE, "Failed to read Jack-server version properties", e);
throw new AssertionError();
@@ -869,9 +872,6 @@
NoSuchAlgorithmException {
{
File clientPEM = new File(getServerDir(), PEM_CLIENT);
- if (clientPEM.exists() && !clientPEM.delete()) {
- throw new IOException("Failed to delete '" + clientPEM.getPath() + "'");
- }
PEMWriter pem = new PEMWriter(clientPEM);
try {
@@ -883,9 +883,6 @@
}
{
File serverPEM = new File(getServerDir(), PEM_SERVER);
- if (serverPEM.exists() && !serverPEM.delete()) {
- throw new IOException("Failed to delete '" + serverPEM.getPath() + "'");
- }
PEMWriter pem = new PEMWriter(serverPEM);
try {
pem.writeCertificate(keystoreServer.getCertificate(SERVER_KEY_ALIAS));
@@ -1120,7 +1117,7 @@
}
}
- public long startingServiceTask() throws ServerClosedException {
+ public long startingServiceTask() {
return startingTask(serviceInfo);
}
@@ -1129,20 +1126,23 @@
}
public long startingAdministrativeTask() throws ServerClosedException {
- return startingTask(adminInfo);
+ synchronized (lock) {
+ if (shuttingDown) {
+ throw new ServerClosedException();
+ }
+
+ return startingTask(adminInfo);
+ }
}
public void endingAdministrativeTask() {
endingTask(adminInfo);
}
- private long startingTask(@Nonnull ServerInfo info) throws ServerClosedException{
+ private long startingTask(@Nonnull ServerInfo info) {
long id;
synchronized (lock) {
- if (shuttingDown) {
- throw new ServerClosedException();
- }
id = info.totalLocal;
info.totalLocal++;
setServerMode(ServerMode.WORK);
diff --git a/server/jack-server/src/com/android/jack/server/PEMWriter.java b/server/jack-server/src/com/android/jack/server/PEMWriter.java
index d770ffb..ecab1cf 100644
--- a/server/jack-server/src/com/android/jack/server/PEMWriter.java
+++ b/server/jack-server/src/com/android/jack/server/PEMWriter.java
@@ -54,21 +54,30 @@
@Nonnull
private final Writer out;
+ @Nonnull
+ private final File targetFile;
+
+
+ @Nonnull
+ private final File tmpFile;
+
public PEMWriter(@Nonnull File file) throws IOException {
- if (!file.exists()) {
- if (!file.createNewFile()) {
- throw new IOException("Failed to create file '" + file.getPath() + "'");
+ targetFile = file;
+ tmpFile = File.createTempFile("jackserver-", file.getName(), file.getParentFile());
+ if (!tmpFile.exists()) {
+ if (!tmpFile.createNewFile()) {
+ throw new IOException("Failed to create temp file '" + tmpFile.getPath() + "'");
}
- if (!(file.setExecutable(false, false)
- && file.setWritable(false, false)
- && file.setReadable(false, false)
- && file.setWritable(true, true)
- && file.setReadable(true, true))) {
- throw new IOException("Failed to set permission of '" + file.getPath() + "'");
+ if (!(tmpFile.setExecutable(false, false)
+ && tmpFile.setWritable(false, false)
+ && tmpFile.setReadable(false, false)
+ && tmpFile.setWritable(true, true)
+ && tmpFile.setReadable(true, true))) {
+ throw new IOException("Failed to set permission of '" + tmpFile.getPath() + "'");
}
}
- out = new OutputStreamWriter(new FileOutputStream(file), CHARSET);
+ out = new OutputStreamWriter(new FileOutputStream(tmpFile), CHARSET);
}
public void writeCertificate(@Nonnull Certificate certificate) throws IOException {
@@ -96,5 +105,9 @@
@Override
public void close() throws IOException {
out.close();
+ if (!tmpFile.renameTo(targetFile)) {
+ throw new IOException("Failed to rename \"" + tmpFile.getPath() + "\" to \""
+ + targetFile.getPath() + "\"");
+ }
}
}
diff --git a/server/jack-server/src/com/android/jack/server/tasks/InstallServer.java b/server/jack-server/src/com/android/jack/server/tasks/InstallServer.java
index a326952..0aabf11 100644
--- a/server/jack-server/src/com/android/jack/server/tasks/InstallServer.java
+++ b/server/jack-server/src/com/android/jack/server/tasks/InstallServer.java
@@ -19,16 +19,31 @@
import com.android.jack.server.JackHttpServer;
import com.android.jack.server.api.v01.NotInstalledException;
import com.android.jack.server.api.v01.ServerException;
+import com.android.sched.util.UncomparableVersion;
+import com.android.sched.util.Version;
+import com.android.sched.util.file.CannotChangePermissionException;
+import com.android.sched.util.file.CannotCreateFileException;
+import com.android.sched.util.file.CannotReadException;
+import com.android.sched.util.file.CannotWriteException;
+import com.android.sched.util.file.Files;
+import com.android.sched.util.location.FileLocation;
+import com.android.sched.util.location.StringLocation;
+import com.android.sched.util.stream.LocationByteStreamSucker;
import org.simpleframework.http.Part;
import org.simpleframework.http.Request;
import org.simpleframework.http.Response;
import org.simpleframework.http.Status;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
import javax.annotation.Nonnull;
@@ -38,6 +53,9 @@
public class InstallServer extends SynchronousAdministrativeTask {
@Nonnull
+ private static final String VERSION_FILE_SUFFIX = "-version.properties";
+
+ @Nonnull
private static final Logger logger = Logger.getLogger(InstallServer.class.getName());
public InstallServer(@Nonnull JackHttpServer jackServer) {
super(jackServer);
@@ -55,6 +73,50 @@
InputStream jarIn = null;
try {
jarIn = jarPart.getInputStream();
+ if (!force) {
+ File tmpServer = Files.createTempFile("jackserver-");
+ try (FileOutputStream out = new FileOutputStream(tmpServer)) {
+ new LocationByteStreamSucker(jarIn, out, new StringLocation("Request input"),
+ new FileLocation(tmpServer)).suck();
+ }
+
+ try (ZipFile zip = new ZipFile(tmpServer)) {
+ ZipEntry entry = zip.getEntry(JackHttpServer.VERSION_CODE + VERSION_FILE_SUFFIX);
+ if (entry == null) {
+ throw new IOException("Given server jar is invalid, it is missing a version file");
+ }
+ try (InputStream versionInput = zip.getInputStream(entry);) {
+ Version candidateVersion = new Version(versionInput);
+ Version currentVerion = jackServer.getVersion();
+
+ try {
+ if (!candidateVersion.isNewerThan(currentVerion)) {
+ if (candidateVersion.equals(currentVerion)) {
+ logger.log(Level.INFO, "Server version "
+ + currentVerion.getVerboseVersion() + " was already installed");
+ return;
+ } else {
+ throw new NotInstalledException("Not installing server "
+ + candidateVersion.getVerboseVersion()
+ + " since it is not newer than current server "
+ + currentVerion.getVerboseVersion());
+ }
+ }
+ } catch (UncomparableVersion e) {
+ if (!candidateVersion.isComparable()) {
+ throw new NotInstalledException("Not installing server '"
+ + candidateVersion.getVerboseVersion() + "' without force request");
+ }
+ // else: current is experimental or eng, candidate is not, lets proceed
+ }
+ }
+ }
+
+ // replace jarIn, the server jar is no longer available from the request
+ jarIn.close();
+ jarIn = new FileInputStream(tmpServer);
+ }
+
jackServer.shutdownServerOnly();
jackServer.getLauncherHandle().replaceServer(
jarIn,
@@ -64,7 +126,8 @@
logger.log(Level.SEVERE, e.getMessage(), e);
response.setStatus(Status.INTERNAL_SERVER_ERROR);
return;
- } catch (IOException e) {
+ } catch (CannotChangePermissionException | CannotReadException | CannotCreateFileException
+ | CannotWriteException | IOException e) {
logger.log(Level.SEVERE, e.getMessage(), e);
response.setStatus(Status.INTERNAL_SERVER_ERROR);
return;
diff --git a/server/jack-server/src/com/android/jack/server/tasks/SynchronousServiceTask.java b/server/jack-server/src/com/android/jack/server/tasks/SynchronousServiceTask.java
index 914bf16..7d943a1 100644
--- a/server/jack-server/src/com/android/jack/server/tasks/SynchronousServiceTask.java
+++ b/server/jack-server/src/com/android/jack/server/tasks/SynchronousServiceTask.java
@@ -17,7 +17,6 @@
package com.android.jack.server.tasks;
import com.android.jack.server.JackHttpServer;
-import com.android.jack.server.JackHttpServer.ServerClosedException;
import org.simpleframework.http.Request;
import org.simpleframework.http.Response;
@@ -47,9 +46,6 @@
try {
long taskId = jackServer.startingServiceTask();
handle(taskId, request, response);
- } catch (ServerClosedException e) {
- response.setContentLength(0);
- response.setStatus(Status.SERVICE_UNAVAILABLE);
} catch (Error | RuntimeException e) {
logger.log(Level.SEVERE, e.getMessage(), e);
response.setContentLength(0);