Skip to content
Permalink
Browse files
JCLOUDS-1333: JCLOUDS-1334: JCLOUDS-1470: Require Java 8 and Guava 22
This allows compatibility with Guava 29.  Also unwind some older
workarounds.
  • Loading branch information
gaul committed Jun 24, 2020
1 parent 20b1394 commit 62767a14610fc1c97c440dbd5ee0f02b276a1069
Show file tree
Hide file tree
Showing 20 changed files with 37 additions and 106 deletions.
@@ -74,19 +74,4 @@
<version>${project.version}</version>
</dependency>
</dependencies>
<profiles>
<profile>
<id>jre1.7</id>
<activation>
<jdk>[1.7,)</jdk>
</activation>
<dependencies>
<dependency>
<groupId>org.apache.jclouds.api</groupId>
<artifactId>filesystem</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</profile>
</profiles>
</project>
@@ -34,6 +34,7 @@
import org.jclouds.date.TimeStamp;
import org.jclouds.http.HttpRequest;
import org.jclouds.http.HttpResponse;
import org.jclouds.http.HttpResponseException;
import org.jclouds.rest.ConfiguresHttpApi;
import org.jclouds.rest.ResourceNotFoundException;
import org.testng.annotations.Test;
@@ -144,7 +145,7 @@ public void testDeleteGroupReturns2xx() {
api.organizationApi().get().deleteGroup("foo");
}

@Test(expectedExceptions = ResourceNotFoundException.class)
@Test(expectedExceptions = HttpResponseException.class)
public void testDeleteGroupFailsOn404() {
ChefApi api = requestSendsResponse(signed(HttpRequest.builder() //
.method("DELETE") //
@@ -85,7 +85,7 @@ public OperatingSystem apply(final Image from) {
} else if (imageName.contains("Oracle")) {
osFamily = OsFamily.OEL;
} else {
final Iterable<String> imageNameParts = Splitter.on(CharMatcher.WHITESPACE).trimResults().split(
final Iterable<String> imageNameParts = Splitter.on(CharMatcher.whitespace()).trimResults().split(
imageName.toLowerCase());

try {
@@ -61,6 +61,7 @@
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;

@Singleton
public class ApplyNovaTemplateOptionsCreateNodesWithGroupEncodedIntoNameThenAddToSet extends
@@ -188,8 +189,7 @@ protected ListenableFuture<AtomicReference<NodeMetadata>> createNodeInGroupWithN
public AtomicReference<NodeAndNovaTemplateOptions> apply(AtomicReference<NodeMetadata> input) {
return NodeAndNovaTemplateOptions.newAtomicReference(input, Atomics.newReference(templateOptions));
}
}
);
}, MoreExecutors.directExecutor());
return Futures.transform(nodeAndNovaTemplateOptions, createAndAddFloatingIpToNode, userExecutor);
} else {
return future;
@@ -49,6 +49,7 @@
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.inject.Inject;

/**
@@ -286,7 +287,7 @@ public void onFailure(final Throwable t) {
outstandingFutures.remove(blobDelFuture);
semaphore.release();
}
});
}, MoreExecutors.directExecutor());
} else {
// It is possible above to acquire a semaphore but not submit any
// task to the executorService. For e.g. if the listing contains
@@ -39,6 +39,7 @@
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.MoreExecutors;
import com.google.inject.assistedinject.Assisted;

/**
@@ -105,7 +106,7 @@ public Image apply(Image input) {
logger.info(">> Adding default image credentials to image(%s)...", template.getName());
return addDefaultCredentialsToImage.apply(input);
}
});
}, MoreExecutors.directExecutor());

Futures.addCallback(future, new FutureCallback<Image>() {
@Override
@@ -117,7 +118,7 @@ public void onSuccess(Image result) {
public void onFailure(Throwable t) {

}
});
}, MoreExecutors.directExecutor());
return future;
}

@@ -183,9 +183,9 @@ public StubSocketOpen(ConcurrentMap<String, NodeMetadata> nodes, @Named("PUBLIC_

@Override
public boolean apply(HostAndPort input) {
if (input.getHostText().indexOf(publicIpPrefix) == -1)
if (input.getHost().indexOf(publicIpPrefix) == -1)
return false;
String id = input.getHostText().replace(publicIpPrefix, "");
String id = input.getHost().replace(publicIpPrefix, "");
NodeMetadata node = nodes.get(id);
return node != null && node.getStatus() == Status.RUNNING;
}
@@ -20,9 +20,6 @@
import static org.jclouds.Constants.PROPERTY_USER_THREADS;
import static org.jclouds.concurrent.DynamicExecutors.newScalingThreadPool;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.io.Closeable;
import java.io.IOException;
import java.util.List;
@@ -57,60 +54,6 @@
@ConfiguresExecutorService
public class ExecutorServiceModule extends AbstractModule {

private static final Method CREATE_STL;
private static final Constructor<SimpleTimeLimiter> CONSTRUCT_STL;
static {
Method create = null;
Constructor ctor = null;
try {
create = SimpleTimeLimiter.class.getDeclaredMethod("create", ExecutorService.class);
} catch (NoSuchMethodException nsme) {
try {
ctor = SimpleTimeLimiter.class.getConstructor(ExecutorService.class);
} catch (NoSuchMethodException nsme2) {
throw new UnsupportedOperationException(
"Can't find SimpleTimeLimiter creator or constructor taking ExecutorService", nsme2);
}
}
CREATE_STL = create;
CONSTRUCT_STL = ctor;
}

/**
* Reflective creation of SimpleTimeLimiter to allow compatibility with Guava 23.0.
* SimpleTimeLimiter.create(ExecutorService) was introduced in Guava 22.0 to replace
* the SimpleTimeLimiter(ExecutorService) constructor, which was deprecated in
* Guava 22.0 and removed in Guava 23.0. The method is public to allow test methods
* in other packages to use it.
* @param executorService the execution service to use when running time-limited tasks
* @return a new instance of SimpleTimeLimiter that uses executorService
*/
public static SimpleTimeLimiter createSimpleTimeLimiter(ExecutorService executorService) {
try {
if (CREATE_STL != null) {
return (SimpleTimeLimiter) CREATE_STL.invoke(null, executorService);
} else if (CONSTRUCT_STL != null) {
return CONSTRUCT_STL.newInstance(executorService);
}
throw new UnsupportedOperationException(
"Can't find SimpleTimeLimiter creator or constructor taking ExecutorService");
} catch (IllegalAccessException iae) {
throw new UnsupportedOperationException("Can't access SimpleTimeLimiter method/ctor", iae);
} catch (InstantiationException ie) {
throw new UnsupportedOperationException("Can't construct SimpleTimeLimiter", ie);
} catch (InvocationTargetException ite) {
Throwable throwable = ite.getCause();
if (throwable instanceof RuntimeException) {
throw (RuntimeException) throwable;
}
if (throwable instanceof Error) {
throw (Error) throwable;
}
throw new UnsupportedOperationException(
"Checked exception thrown while creating SimpleTimeLimiter", throwable);
}
}

static final class ShutdownExecutorOnClose implements Closeable {
@Resource
private Logger logger = Logger.NULL;
@@ -170,7 +113,7 @@ protected void configure() { // NO_UCD
@Provides
@Singleton
final TimeLimiter timeLimiter(@Named(PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) {
return createSimpleTimeLimiter(userExecutor);
return SimpleTimeLimiter.create(userExecutor);
}

@Provides
@@ -59,13 +59,13 @@ public class InetSocketAddressConnect implements SocketOpen {

@Override
public boolean apply(HostAndPort socketA) {
InetSocketAddress socketAddress = new InetSocketAddress(socketA.getHostText(), socketA
InetSocketAddress socketAddress = new InetSocketAddress(socketA.getHost(), socketA
.getPort());
Socket socket = null;
try {
logger.trace("testing socket %s", socketAddress);
socket = new Socket(
proxyForURI.apply(URI.create("socket://" + socketA.getHostText() + ":" + socketA.getPort())));
proxyForURI.apply(URI.create("socket://" + socketA.getHost() + ":" + socketA.getPort())));
socket.setReuseAddress(false);
socket.setSoLinger(false, 1);
socket.setSoTimeout(timeout);
@@ -67,7 +67,7 @@ public Proxy apply(URI endpoint) {
return Proxy.NO_PROXY;
}
if (config.getProxy().isPresent()) {
SocketAddress addr = new InetSocketAddress(config.getProxy().get().getHostText(), config.getProxy().get()
SocketAddress addr = new InetSocketAddress(config.getProxy().get().getHost(), config.getProxy().get()
.getPort());
Proxy proxy = new Proxy(config.getType(), addr);

@@ -115,7 +115,7 @@ public Object invoke(Invocation invocation) {
* if our thread is interrupted during execution
* @throws UncheckedTimeoutException
* if the time limit is reached
* @see TimeLimiter#callWithTimeout(Callable, long, TimeUnit, boolean)
* @see TimeLimiter#callWithTimeout(Callable, long, TimeUnit)
*/
public Object invokeWithTimeout(final Invocation invocation, final long limitNanos) {
String commandName = config.getCommandName(invocation);
@@ -125,7 +125,7 @@ public Object invokeWithTimeout(final Invocation invocation, final long limitNan
logger.debug(">> blocking on %s for %s", invocation, limitNanos);
try {
return timeLimiter
.callWithTimeout(new InvokeAndTransform(commandName, command), limitNanos, NANOSECONDS, true);
.callWithTimeout(new InvokeAndTransform(commandName, command), limitNanos, NANOSECONDS);
} catch (Throwable t) {
try {
return fallback.createOrPropagate(t);
@@ -22,7 +22,6 @@
import static org.jclouds.Constants.PROPERTY_IDEMPOTENT_METHODS;
import static org.jclouds.Constants.PROPERTY_MAX_RETRIES;
import static org.jclouds.Constants.PROPERTY_USER_THREADS;
import static org.jclouds.concurrent.config.ExecutorServiceModule.createSimpleTimeLimiter;
import static org.testng.Assert.assertEquals;

import java.io.IOException;
@@ -81,6 +80,7 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.io.ByteSource;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.SimpleTimeLimiter;
import com.google.common.util.concurrent.TimeLimiter;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
@@ -235,7 +235,7 @@ public void configure() {
@Provides
@Singleton
TimeLimiter timeLimiter(@Named(PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) {
return createSimpleTimeLimiter(userExecutor);
return SimpleTimeLimiter.create(userExecutor);
}
}

@@ -22,7 +22,6 @@
import static com.google.inject.name.Names.named;
import static org.easymock.EasyMock.createMock;
import static org.jclouds.Constants.PROPERTY_USER_THREADS;
import static org.jclouds.concurrent.config.ExecutorServiceModule.createSimpleTimeLimiter;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;

@@ -51,6 +50,7 @@
import com.google.common.collect.TreeMultimap;
import com.google.common.reflect.Invokable;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.common.util.concurrent.SimpleTimeLimiter;
import com.google.common.util.concurrent.TimeLimiter;
import com.google.inject.AbstractModule;
import com.google.inject.Injector;
@@ -84,7 +84,7 @@ protected void configure() {
@Provides
@Singleton
TimeLimiter timeLimiter(@Named(PROPERTY_USER_THREADS) ListeningExecutorService userExecutor) {
return createSimpleTimeLimiter(userExecutor);
return SimpleTimeLimiter.create(userExecutor);
}
}

@@ -98,7 +98,7 @@ void verifyMocks() {
public void testMethodWithTimeoutRunsTimeLimiter() throws Exception {
expect(config.getTimeoutNanos(get)).andReturn(Optional.of(250000000L));
InvokeAndTransform invoke = invokeHttpMethod.new InvokeAndTransform("ns:get", getCommand);
expect(timeLimiter.callWithTimeout(invoke, 250000000, TimeUnit.NANOSECONDS, true)).andReturn(response);
expect(timeLimiter.callWithTimeout(invoke, 250000000, TimeUnit.NANOSECONDS)).andReturn(response);
replay(http, timeLimiter, fallback, config);
invokeHttpMethod.apply(get);
}
@@ -125,7 +125,7 @@ public void testTimeLimitedRunsFallbackCreateOrPropagate() throws Exception {
IllegalStateException exception = new IllegalStateException();
expect(config.getTimeoutNanos(get)).andReturn(Optional.of(250000000L));
InvokeAndTransform invoke = invokeHttpMethod.new InvokeAndTransform("ns:get", getCommand);
expect(timeLimiter.callWithTimeout(invoke, 250000000, TimeUnit.NANOSECONDS, true)).andThrow(exception);
expect(timeLimiter.callWithTimeout(invoke, 250000000, TimeUnit.NANOSECONDS)).andThrow(exception);
expect(fallback.createOrPropagate(exception)).andReturn(fallbackResponse);
replay(http, timeLimiter, fallback, config);
assertEquals(invokeHttpMethod.apply(get), fallbackResponse);
@@ -126,7 +126,7 @@ public void close() throws IOException {
public JschSshClient(ProxyConfig proxyConfig, BackoffLimitedRetryHandler backoffLimitedRetryHandler, HostAndPort socket,
LoginCredentials loginCredentials, int timeout, Optional<Connector> agentConnector) {
this.user = checkNotNull(loginCredentials, "loginCredentials").getUser();
this.host = checkNotNull(socket, "socket").getHostText();
this.host = checkNotNull(socket, "socket").getHost();
checkArgument(socket.getPort() > 0, "ssh port must be greater then zero" + socket.getPort());
checkArgument(loginCredentials.getOptionalPassword().isPresent() || loginCredentials.hasUnencryptedPrivateKey() || agentConnector.isPresent(),
"you must specify a password, a key or an SSH agent needs to be available");
@@ -89,12 +89,12 @@ public Builder proxy(ProxyConfig proxyConfig) {
Optional<Credentials> creds = proxyConfig.getCredentials();
switch (proxyConfig.getType()) {
case HTTP:
ProxyHTTP httpProxy = new ProxyHTTP(proxyEndpoint.get().getHostText(), proxyEndpoint.get().getPort());
ProxyHTTP httpProxy = new ProxyHTTP(proxyEndpoint.get().getHost(), proxyEndpoint.get().getPort());
if (creds.isPresent())
httpProxy.setUserPasswd(creds.get().identity, creds.get().credential);
return proxy(httpProxy);
case SOCKS:
ProxySOCKS5 socksProxy = new ProxySOCKS5(proxyEndpoint.get().getHostText(), proxyEndpoint.get().getPort());
ProxySOCKS5 socksProxy = new ProxySOCKS5(proxyEndpoint.get().getHost(), proxyEndpoint.get().getPort());
if (creds.isPresent())
socksProxy.setUserPasswd(creds.get().identity, creds.get().credential);
return proxy(socksProxy);
@@ -167,7 +167,7 @@ public void clear() {
public Session create() throws Exception {
JSch jsch = new JSch();
session = jsch
.getSession(loginCredentials.getUser(), hostAndPort.getHostText(), hostAndPort.getPortOrDefault(22));
.getSession(loginCredentials.getUser(), hostAndPort.getHost(), hostAndPort.getPortOrDefault(22));
if (sessionTimeout != 0)
session.setTimeout(sessionTimeout);
if (loginCredentials.hasUnencryptedPrivateKey()) {
@@ -157,7 +157,7 @@ public SSHClient create() throws Exception {
if (sessionTimeout != 0) {
ssh.setTimeout(sessionTimeout);
}
ssh.connect(hostAndPort.getHostText(), hostAndPort.getPortOrDefault(22));
ssh.connect(hostAndPort.getHost(), hostAndPort.getPortOrDefault(22));
if (loginCredentials.hasUnencryptedPrivateKey()) {
OpenSSHKeyFile key = new OpenSSHKeyFile();
key.init(loginCredentials.getOptionalPrivateKey().get(), null);
@@ -144,7 +144,7 @@ public void close() throws IOException {
public SshjSshClient(BackoffLimitedRetryHandler backoffLimitedRetryHandler, HostAndPort socket,
LoginCredentials loginCredentials, int timeout, Optional<Connector> agentConnector) {
this.user = checkNotNull(loginCredentials, "loginCredentials").getUser();
this.host = checkNotNull(socket, "socket").getHostText();
this.host = checkNotNull(socket, "socket").getHost();
checkArgument(socket.getPort() > 0, "ssh port must be greater then zero" + socket.getPort());
checkArgument(loginCredentials.getOptionalPassword().isPresent() || loginCredentials.hasUnencryptedPrivateKey() || agentConnector.isPresent(),
"you must specify a password, a key or an SSH agent needs to be available");
@@ -217,13 +217,13 @@
</developers>

<properties>
<maven.compile.source>1.7</maven.compile.source>
<maven.compile.target>1.7</maven.compile.target>
<jdk.version>1.7</jdk.version>
<maven.compile.source>1.8</maven.compile.source>
<maven.compile.target>1.8</maven.compile.target>
<jdk.version>1.8</jdk.version>
<maven.compile.deprecation>true</maven.compile.deprecation>
<maven.site.url.base>gitsite:git@github.com/jclouds/jclouds-maven-site.git</maven.site.url.base>
<guava.version>18.0</guava.version>
<guava.osgi.import>com.google.common.*;version="[18.0,24.0.0)"</guava.osgi.import>
<guava.version>22.0</guava.version>
<guava.osgi.import>com.google.common.*;version="[22.0,30.0.0)"</guava.osgi.import>
<guice.version>3.0</guice.version>
<okhttp.version>2.2.0</okhttp.version>
<okio.osgi.import>okio;version="[1.2.0,1.3)"</okio.osgi.import>
@@ -585,7 +585,7 @@
<configuration>
<rules>
<requireJavaVersion>
<version>[1.7,)</version>
<version>[1.8,)</version>
</requireJavaVersion>
<requireMavenVersion>
<version>[3.0.2,)</version>
@@ -40,7 +40,7 @@ public void validate(String name) {

if (name == null || name.length() < minLength || name.length() > maxLength)
throw exception(name, "Can't be null or empty. Length must be " + minLength + " to " + maxLength + " symbols");
if (!CharMatcher.JAVA_LETTER_OR_DIGIT.matches(name.charAt(0)))
if (!Character.isLetterOrDigit(name.charAt(0)))
throw exception(name, "Should start with letter/number");

CharMatcher range = getAcceptableRange();

0 comments on commit 62767a1

Please sign in to comment.