Version 1.10.14.

- Remove no longer needed no-unixsocket.patch.
- Add workaround for compiling tests with JDK 11.
This commit is contained in:
Jerry James 2020-08-14 21:58:19 -06:00
parent 485b9ca2fe
commit 272085e9b0
4 changed files with 48 additions and 483 deletions

View File

@ -1,5 +1,5 @@
--- byte-buddy/pom.xml.orig 2018-11-22 17:18:25.000000000 +0000 --- byte-buddy/pom.xml.orig 2020-07-31 08:09:49.000000000 -0600
+++ byte-buddy/pom.xml 2018-11-30 17:48:48.655978937 +0000 +++ byte-buddy/pom.xml 2020-08-14 13:55:09.300521492 -0600
@@ -26,8 +26,6 @@ @@ -26,8 +26,6 @@
--> -->
@ -40,9 +40,9 @@
</dependency> </dependency>
</dependencies> </dependencies>
@@ -99,47 +104,19 @@ @@ -105,12 +110,6 @@
<createDependencyReducedPom>true</createDependencyReducedPom> <createDependencyReducedPom>true</createDependencyReducedPom>
<createSourcesJar>true</createSourcesJar> <createSourcesJar>${bytebuddy.extras}</createSourcesJar>
<shadeSourcesContent>true</shadeSourcesContent> <shadeSourcesContent>true</shadeSourcesContent>
- <relocations> - <relocations>
- <relocation> - <relocation>
@ -50,24 +50,42 @@
- <shadedPattern>${shade.target}</shadedPattern> - <shadedPattern>${shade.target}</shadedPattern>
- </relocation> - </relocation>
- </relocations> - </relocations>
- <filters> <filters>
<filter>
<artifact>net.bytebuddy:byte-buddy-dep:*</artifact>
@@ -118,30 +117,6 @@
<exclude>META-INF/MANIFEST.MF</exclude>
</excludes>
</filter>
- <filter>
- <artifact>org.ow2.asm:*</artifact>
- <excludes>
- <exclude>META-INF/MANIFEST.MF</exclude>
- <exclude>**/module-info.class</exclude>
- <exclude>**/LICENSE</exclude>
- <exclude>**/NOTICE</exclude>
- </excludes>
- </filter>
- <filter> - <filter>
- <artifact>org.ow2.asm:asm-commons</artifact> - <artifact>org.ow2.asm:asm-commons</artifact>
- <includes> - <includes>
- <include>org/objectweb/asm/commons/Remapper.class</include> - <include>org/objectweb/asm/commons/AnnotationRemapper.**</include>
- <include>org/objectweb/asm/commons/SimpleRemapper.class</include> - <include>org/objectweb/asm/commons/ClassRemapper.**</include>
- <include>org/objectweb/asm/commons/ClassRemapper.class</include> - <include>org/objectweb/asm/commons/FieldRemapper.**</include>
- <include>org/objectweb/asm/commons/AnnotationRemapper.class</include> - <include>org/objectweb/asm/commons/MethodRemapper.**</include>
- <include>org/objectweb/asm/commons/FieldRemapper.class</include> - <include>org/objectweb/asm/commons/ModuleHashesAttribute.**</include>
- <include>org/objectweb/asm/commons/MethodRemapper.class</include> - <include>org/objectweb/asm/commons/ModuleRemapper.**</include>
- <include>org/objectweb/asm/commons/ModuleRemapper.class</include> - <include>org/objectweb/asm/commons/RecordComponentRemapper.**</include>
- <include>org/objectweb/asm/commons/SignatureRemapper.class</include> - <include>org/objectweb/asm/commons/Remapper.**</include>
- <include>org/objectweb/asm/commons/SignatureRemapper.**</include>
- <include>org/objectweb/asm/commons/SimpleRemapper.**</include>
- </includes> - </includes>
- </filter> - </filter>
- </filters> </filters>
<transformers> <transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer"> <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>net.bytebuddy.build.Plugin$Engine$Default</mainClass> @@ -151,21 +126,14 @@
<resource>META-INF/LICENSE</resource>
</transformer> </transformer>
</transformers> </transformers>
+ <artifactSet> + <artifactSet>

View File

@ -3,18 +3,15 @@
%bcond_with bootstrap %bcond_with bootstrap
Name: byte-buddy Name: byte-buddy
Version: 1.9.5 Version: 1.10.14
Release: 9%{?dist} Release: 1%{?dist}
Summary: Runtime code generation for the Java virtual machine Summary: Runtime code generation for the Java virtual machine
License: ASL 2.0 License: ASL 2.0
URL: http://bytebuddy.net/ URL: http://bytebuddy.net/
Source0: https://github.com/raphw/byte-buddy/archive/%{name}-%{version}.tar.gz Source0: https://github.com/raphw/byte-buddy/archive/%{name}-%{version}.tar.gz
# Patch out use of a unixsocket lib that is not in Fedora
Patch0: no-unixsocket.patch
# Patch the build to avoid bundling inside shaded jars # Patch the build to avoid bundling inside shaded jars
Patch1: avoid-bundling-asm.patch Patch0: avoid-bundling-asm.patch
BuildRequires: maven-local BuildRequires: maven-local
%if %{without bootstrap} %if %{without bootstrap}
@ -28,6 +25,8 @@ BuildRequires: mvn(org.mockito:mockito-core)
BuildRequires: mvn(org.ow2.asm:asm-analysis) BuildRequires: mvn(org.ow2.asm:asm-analysis)
BuildRequires: mvn(org.ow2.asm:asm-util) BuildRequires: mvn(org.ow2.asm:asm-util)
%endif %endif
BuildRequires: mvn(net.java.dev.jna:jna)
BuildRequires: mvn(net.java.dev.jna:jna-platform)
BuildRequires: mvn(org.apache.felix:maven-bundle-plugin) BuildRequires: mvn(org.apache.felix:maven-bundle-plugin)
BuildRequires: mvn(org.apache.maven:maven-core) BuildRequires: mvn(org.apache.maven:maven-core)
BuildRequires: mvn(org.apache.maven:maven-plugin-api) BuildRequires: mvn(org.apache.maven:maven-plugin-api)
@ -77,12 +76,14 @@ This package contains API documentation for %{name}.
%prep %prep
%setup -q -n %{name}-%{name}-%{version} %setup -q -n %{name}-%{name}-%{version}
%patch0 %patch0
%patch1
# Remove pre-built jars # Remove pre-built jars
find -name *.jar -delete find -name *.jar -delete
find -name *.class -delete find -name *.class -delete
# JDK 11 does not know about the Java record type
rm byte-buddy-dep/src/precompiled/java/net/bytebuddy/test/precompiled/SampleRecord.java
# Cause pre-compiled stuff to be re-compiled # Cause pre-compiled stuff to be re-compiled
mv byte-buddy-dep/src/precompiled/java/net/bytebuddy/build/*.java \ mv byte-buddy-dep/src/precompiled/java/net/bytebuddy/build/*.java \
byte-buddy-dep/src/main/java/net/bytebuddy/build byte-buddy-dep/src/main/java/net/bytebuddy/build
@ -92,6 +93,7 @@ mv byte-buddy-dep/src/precompiled/java/net/bytebuddy/test/precompiled/*.java \
# Don't ship android or benchmark modules # Don't ship android or benchmark modules
%pom_disable_module byte-buddy-android %pom_disable_module byte-buddy-android
%pom_disable_module byte-buddy-android-test
%pom_disable_module byte-buddy-benchmark %pom_disable_module byte-buddy-benchmark
# Don't ship gradle plugin # Don't ship gradle plugin
@ -153,6 +155,11 @@ sed -i -e '/SuppressFBWarnings/d' $(grep -lr SuppressFBWarnings)
%license LICENSE NOTICE %license LICENSE NOTICE
%changelog %changelog
* Fri Aug 14 2020 Jerry James <loganjerry@gmail.com> - 1.10.14-1
- Version 1.10.14
- Remove no longer needed no-unixsocket.patch
- Add workaround for compiling tests with JDK 11
* Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.9.5-9 * Mon Jul 27 2020 Fedora Release Engineering <releng@fedoraproject.org> - 1.9.5-9
- Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild - Rebuilt for https://fedoraproject.org/wiki/Fedora_33_Mass_Rebuild

View File

@ -1,460 +0,0 @@
--- byte-buddy-agent/pom.xml.orig 2018-11-30 11:43:29.016481386 +0000
+++ byte-buddy-agent/pom.xml 2018-11-30 11:43:42.676439662 +0000
@@ -15,7 +15,6 @@
<bytebuddy.agent>net.bytebuddy.agent.Installer</bytebuddy.agent>
<attach.package.sun>com.sun.tools.attach</attach.package.sun>
<attach.package.ibm>com.ibm.tools.attach</attach.package.ibm>
- <version.unixsocket>2.0.4</version.unixsocket>
<packages.list>net.bytebuddy.agent</packages.list>
</properties>
@@ -30,12 +29,6 @@
<dependencies>
<dependency>
- <groupId>com.kohlschutter.junixsocket</groupId>
- <artifactId>junixsocket-native-common</artifactId>
- <version>${version.unixsocket}</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${version.junit}</version>
--- byte-buddy-agent/src/main/java/net/bytebuddy/agent/ByteBuddyAgent.java.orig 2018-11-30 11:22:23.274443432 +0000
+++ byte-buddy-agent/src/main/java/net/bytebuddy/agent/ByteBuddyAgent.java 2018-11-30 11:42:22.236685381 +0000
@@ -541,8 +541,7 @@
ForStandardToolsJarVm.JVM_ROOT,
ForStandardToolsJarVm.JDK_ROOT,
ForStandardToolsJarVm.MACINTOSH,
- ForUserDefinedToolsJar.INSTANCE,
- ForUnixHotSpotVm.INSTANCE);
+ ForUserDefinedToolsJar.INSTANCE);
/**
* Attempts the creation of an accessor for a specific JVM's attachment API.
@@ -922,28 +921,6 @@
}
}
}
-
- /**
- * An attachment provider using a custom protocol implementation for HotSpot on Unix.
- */
- enum ForUnixHotSpotVm implements AttachmentProvider {
-
- /**
- * The singleton instance.
- */
- INSTANCE;
-
- /**
- * {@inheritDoc}
- */
- public Accessor attempt() {
- try {
- return new Accessor.Simple.WithoutExternalAttachment(VirtualMachine.ForHotSpot.OnUnix.assertAvailability());
- } catch (Throwable ignored) {
- return Accessor.Unavailable.INSTANCE;
- }
- }
- }
/**
* A compound attachment provider that attempts the attachment by delegation to other providers. If
--- byte-buddy-agent/src/main/java/net/bytebuddy/agent/VirtualMachine.java.orig 2018-11-30 11:22:55.830341642 +0000
+++ byte-buddy-agent/src/main/java/net/bytebuddy/agent/VirtualMachine.java 2018-11-30 11:38:21.698438915 +0000
@@ -16,8 +16,6 @@
package net.bytebuddy.agent;
import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
-import org.newsclub.net.unix.AFUNIXSocket;
-import org.newsclub.net.unix.AFUNIXSocketAddress;
import java.io.File;
import java.io.IOException;
@@ -172,213 +170,5 @@
*/
protected abstract void write(byte[] buffer) throws IOException;
- /**
- * A virtual machine implementation for a HotSpot VM running on Unix.
- */
- public static class OnUnix extends ForHotSpot {
-
- /**
- * The default amount of attempts to connect.
- */
- private static final int DEFAULT_ATTEMPTS = 10;
-
- /**
- * The default pause between two attempts.
- */
- private static final long DEFAULT_PAUSE = 200;
-
- /**
- * The default socket timeout.
- */
- private static final long DEFAULT_TIMEOUT = 5000;
-
- /**
- * The temporary directory on Unix systems.
- */
- private static final String TEMPORARY_DIRECTORY = "/tmp";
-
- /**
- * The name prefix for a socket.
- */
- private static final String SOCKET_FILE_PREFIX = ".java_pid";
-
- /**
- * The name prefix for an attachment file indicator.
- */
- private static final String ATTACH_FILE_PREFIX = ".attach_pid";
-
- /**
- * The Unix socket to use for communication. The containing object is supposed to be an instance
- * of {@link AFUNIXSocket} which is however not set to avoid eager loading
- */
- private final Object socket;
-
- /**
- * The number of attempts to connect.
- */
- private final int attempts;
-
- /**
- * The time to pause between attempts.
- */
- private final long pause;
-
- /**
- * The socket timeout.
- */
- private final long timeout;
-
- /**
- * The time unit of the pause time.
- */
- private final TimeUnit timeUnit;
-
- /**
- * Creates a new VM implementation for a HotSpot VM running on Unix.
- *
- * @param processId The process id of the target VM.
- * @param socket The Unix socket to use for communication.
- * @param attempts The number of attempts to connect.
- * @param pause The pause time between two VMs.
- * @param timeout The socket timeout.
- * @param timeUnit The time unit of the pause time.
- */
- public OnUnix(String processId, Object socket, int attempts, long pause, long timeout, TimeUnit timeUnit) {
- super(processId);
- this.socket = socket;
- this.attempts = attempts;
- this.pause = pause;
- this.timeout = timeout;
- this.timeUnit = timeUnit;
- }
-
- /**
- * Asserts the availability of this virtual machine implementation. If the Unix socket library is missing or
- * if this VM does not support Unix socket communication, a {@link Throwable} is thrown.
- *
- * @return This virtual machine type.
- * @throws Throwable If this attachment method is not available.
- */
- public static Class<?> assertAvailability() throws Throwable {
- try {
- Class<?> moduleType = Class.forName("java.lang.Module");
- Method getModule = Class.class.getMethod("getModule"), canRead = moduleType.getMethod("canRead", moduleType);
- Object thisModule = getModule.invoke(OnUnix.class), otherModule = getModule.invoke(AFUNIXSocket.class);
- if (!(Boolean) canRead.invoke(thisModule, otherModule)) {
- moduleType.getMethod("addReads", moduleType).invoke(thisModule, otherModule);
- }
- return doAssertAvailability();
- } catch (ClassNotFoundException ignored) {
- return doAssertAvailability();
- }
- }
-
- /**
- * Asserts the availability of this virtual machine implementation.
- *
- * @return This virtual machine type.
- */
- private static Class<?> doAssertAvailability() {
- if (!AFUNIXSocket.isSupported()) {
- throw new IllegalStateException("POSIX sockets are not supported on the current system");
- } else if (!System.getProperty("java.vm.name").toLowerCase(Locale.US).contains("hotspot")) {
- throw new IllegalStateException("Cannot apply attachment on non-Hotspot compatible VM");
- } else {
- return OnUnix.class;
- }
- }
-
- /**
- * Attaches to the supplied VM process.
- *
- * @param processId The process id of the target VM.
- * @return An appropriate virtual machine implementation.
- * @throws IOException If an I/O exception occurs.
- */
- public static VirtualMachine attach(String processId) throws IOException {
- return new OnUnix(processId, AFUNIXSocket.newInstance(), DEFAULT_ATTEMPTS, DEFAULT_PAUSE, DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
- }
-
- /**
- * {@inheritDoc}
- */
- @SuppressFBWarnings(value = "DMI_HARDCODED_ABSOLUTE_FILENAME", justification = "This is a Unix-specific implementation")
- protected void connect() throws IOException {
- File socketFile = new File(TEMPORARY_DIRECTORY, SOCKET_FILE_PREFIX + processId);
- if (!socketFile.exists()) {
- String target = ATTACH_FILE_PREFIX + processId, path = "/proc/" + processId + "/cwd/" + target;
- File attachFile = new File(path);
- try {
- if (!attachFile.createNewFile() && !attachFile.isFile()) {
- throw new IllegalStateException("Could not create attach file: " + attachFile);
- }
- } catch (IOException ignored) {
- attachFile = new File(TEMPORARY_DIRECTORY, target);
- if (!attachFile.createNewFile() && !attachFile.isFile()) {
- throw new IllegalStateException("Could not create attach file: " + attachFile);
- }
- }
- try {
- // The HotSpot attachment API attempts to send the signal to all children of a process
- Process process = Runtime.getRuntime().exec("kill -3 " + processId);
- int attempts = this.attempts;
- boolean killed = false;
- do {
- try {
- if (process.exitValue() != 0) {
- throw new IllegalStateException("Error while sending signal to target VM: " + processId);
- }
- killed = true;
- break;
- } catch (IllegalThreadStateException ignored) {
- attempts -= 1;
- Thread.sleep(timeUnit.toMillis(pause));
- }
- } while (attempts > 0);
- if (!killed) {
- throw new IllegalStateException("Target VM did not respond to signal: " + processId);
- }
- attempts = this.attempts;
- while (attempts-- > 0 && !socketFile.exists()) {
- Thread.sleep(timeUnit.toMillis(pause));
- }
- if (!socketFile.exists()) {
- throw new IllegalStateException("Target VM did not respond: " + processId);
- }
- } catch (InterruptedException exception) {
- throw new IllegalStateException("Interrupted during wait for process", exception);
- } finally {
- if (!attachFile.delete()) {
- attachFile.deleteOnExit();
- }
- }
- }
- if (timeout != 0) {
- ((AFUNIXSocket) socket).setSoTimeout((int) timeUnit.toMillis(timeout));
- }
- ((AFUNIXSocket) socket).connect(new AFUNIXSocketAddress(socketFile));
- }
-
- /**
- * {@inheritDoc}
- */
- public int read(byte[] buffer) throws IOException {
- return ((AFUNIXSocket) this.socket).getInputStream().read(buffer);
- }
-
- /**
- * {@inheritDoc}
- */
- public void write(byte[] buffer) throws IOException {
- ((AFUNIXSocket) this.socket).getOutputStream().write(buffer);
- }
-
- /**
- * {@inheritDoc}
- */
- public void detach() throws IOException {
- ((AFUNIXSocket) this.socket).close();
- }
- }
}
}
--- byte-buddy-agent/src/test/java/net/bytebuddy/test/utility/UnixSocketRule.java 2018-11-22 17:18:25.000000000 +0000
+++ /dev/null 2018-10-26 11:27:39.627999956 +0100
@@ -1,48 +0,0 @@
-package net.bytebuddy.test.utility;
-
-import org.junit.rules.MethodRule;
-import org.junit.runners.model.FrameworkMethod;
-import org.junit.runners.model.Statement;
-import org.newsclub.net.unix.AFUNIXSocket;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-import java.util.logging.Logger;
-
-public class UnixSocketRule implements MethodRule {
-
- private final boolean enabled;
-
- public UnixSocketRule() {
- boolean enabled;
- try {
- Class.forName(AFUNIXSocket.class.getName(), true, UnixSocketRule.class.getClassLoader());
- enabled = true;
- } catch (Throwable ignored) {
- enabled = false;
- }
- this.enabled = enabled;
- }
-
- public Statement apply(Statement base, FrameworkMethod method, Object target) {
- return enabled || method.getAnnotation(Enforce.class) == null
- ? base
- : new NoOpStatement();
- }
-
- @Retention(RetentionPolicy.RUNTIME)
- @Target(ElementType.METHOD)
- public @interface Enforce {
-
- }
-
- private static class NoOpStatement extends Statement {
-
- public void evaluate() {
- Logger.getLogger("net.bytebuddy").warning("Ignoring Unix sockets on this machine");
- }
- }
-}
-
--- byte-buddy-agent/src/test/java/net/bytebuddy/agent/VirtualMachineForHotSpotTest.java 2018-11-22 17:18:25.000000000 +0000
+++ /dev/null 2018-10-26 11:27:39.627999956 +0100
@@ -1,116 +0,0 @@
-package net.bytebuddy.agent;
-
-import net.bytebuddy.test.utility.UnixSocketRule;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.rules.MethodRule;
-import org.mockito.InOrder;
-
-import java.io.IOException;
-
-import static org.mockito.Mockito.inOrder;
-import static org.mockito.Mockito.spy;
-
-public class VirtualMachineForHotSpotTest {
-
- @Rule
- public MethodRule unixSocketRule = new UnixSocketRule();
-
- @Test
- @UnixSocketRule.Enforce
- public void testAttachment() throws Exception {
- VirtualMachine.ForHotSpot virtualMachine = spy(new PseudoMachine(
- "0".getBytes("UTF-8"),
- new byte[]{10}
- ));
- virtualMachine.loadAgent("foo", "bar");
- InOrder order = inOrder(virtualMachine);
- order.verify(virtualMachine).connect();
- order.verify(virtualMachine).write("1".getBytes("UTF-8"));
- order.verify(virtualMachine).write(new byte[1]);
- order.verify(virtualMachine).write("load".getBytes("UTF-8"));
- order.verify(virtualMachine).write(new byte[1]);
- order.verify(virtualMachine).write("instrument".getBytes("UTF-8"));
- order.verify(virtualMachine).write(new byte[1]);
- order.verify(virtualMachine).write(Boolean.FALSE.toString().getBytes("UTF-8"));
- order.verify(virtualMachine).write(new byte[1]);
- order.verify(virtualMachine).write("foo=bar".getBytes("UTF-8"));
- order.verify(virtualMachine).write(new byte[1]);
- }
-
- @Test
- @UnixSocketRule.Enforce
- public void testAttachmentWithoutArgument() throws Exception {
- VirtualMachine.ForHotSpot virtualMachine = spy(new PseudoMachine(
- "0".getBytes("UTF-8"),
- new byte[]{10}
- ));
- virtualMachine.loadAgent("foo", null);
- InOrder order = inOrder(virtualMachine);
- order.verify(virtualMachine).connect();
- order.verify(virtualMachine).write("1".getBytes("UTF-8"));
- order.verify(virtualMachine).write(new byte[1]);
- order.verify(virtualMachine).write("load".getBytes("UTF-8"));
- order.verify(virtualMachine).write(new byte[1]);
- order.verify(virtualMachine).write("instrument".getBytes("UTF-8"));
- order.verify(virtualMachine).write(new byte[1]);
- order.verify(virtualMachine).write(Boolean.FALSE.toString().getBytes("UTF-8"));
- order.verify(virtualMachine).write(new byte[1]);
- order.verify(virtualMachine).write("foo".getBytes("UTF-8"));
- order.verify(virtualMachine).write(new byte[1]);
- }
-
- @Test(expected = IOException.class)
- @UnixSocketRule.Enforce
- public void testAttachmentIncompatibleProtocol() throws Exception {
- new PseudoMachine(
- "1".getBytes("UTF-8"),
- "0".getBytes("UTF-8"),
- "1".getBytes("UTF-8"),
- new byte[]{10}
- ).loadAgent("foo", null);
- }
-
- @Test(expected = IllegalStateException.class)
- @UnixSocketRule.Enforce
- public void testAttachmentUnknownError() throws Exception {
- new PseudoMachine(
- "1".getBytes("UTF-8"),
- new byte[]{10},
- "foo".getBytes("UTF-8")
- ).loadAgent("foo", null);
- }
-
- private static class PseudoMachine extends VirtualMachine.ForHotSpot {
-
- private final byte[][] read;
-
- private int index;
-
- private PseudoMachine(byte[]... read) {
- super(null);
- this.read = read;
- }
-
- public void detach() {
- /* empty */
- }
-
- protected void connect() {
- /* empty */
- }
-
- protected int read(byte[] buffer) {
- if (index == read.length) {
- return -1;
- }
- byte[] read = this.read[index++];
- System.arraycopy(read, 0, buffer, 0, read.length);
- return read.length;
- }
-
- protected void write(byte[] buffer) {
- /* empty */
- }
- }
-}
\ No newline at end of file

View File

@ -1 +1 @@
SHA512 (byte-buddy-1.9.5.tar.gz) = 6f34e57afa2be4e846f6ffbfe0c1936dcc67c674a876f9be9ae988205c3723a507302881fe0731d26830d6f3973bc71cde781f9a11e766e51312316b1c911193 SHA512 (byte-buddy-1.10.14.tar.gz) = e4007227db2710c8861866f5cdc61ab4e54541aba372dd18b5c0edd81ab9962de5463314c823644a30aedab79ef80f7a8040e77e567e5612ae69bec13f0285b2