Commit 5e0d4694 authored by Rajiv Prabhakar's avatar Rajiv Prabhakar
Browse files

v2.0.3 release: major breaking changes

- Exceptions renamed and moved to common exception package, as top-level classes
- ThreadUtilc.call(Callable) added
- Misc test enhancements
parent 478e77d8
Pipeline #23598900 passed with stage
in 1 minute and 44 seconds
......@@ -6,7 +6,7 @@
<groupId>com.rajivprab</groupId>
<artifactId>cava</artifactId>
<version>2.0.2</version>
<version>2.0.3</version>
<name>Cava: Clean Java</name>
<description>A library that enables users to write minimal, clean and simple Java</description>
......
......@@ -3,7 +3,8 @@ package org.rajivprab.cava;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.io.input.BoundedInputStream;
import org.rajivprab.cava.IOUtilc.IoException;
import org.rajivprab.cava.exception.IOExceptionc;
import org.rajivprab.cava.exception.CheckedExceptionWrapper;
import java.io.File;
import java.io.FileNotFoundException;
......@@ -28,7 +29,7 @@ public class FileUtilc {
Validatec.equals(stream.read(), IOUtils.EOF, SizeLimitExceededException.class,
"Stream exceeded " + maxSize / 1024 + " kB");
} catch (IOException e) {
throw new IoException(e);
throw new IOExceptionc(e);
}
}
......@@ -36,7 +37,7 @@ public class FileUtilc {
try {
FileUtils.copyToFile(stream, file);
} catch (IOException e) {
throw new IoException(e);
throw new IOExceptionc(e);
}
}
......@@ -44,7 +45,7 @@ public class FileUtilc {
try {
return FileUtils.readFileToString(file, IOUtilc.CHARSET_USED);
} catch (IOException e) {
throw new IOUtilc.IoException(e);
throw new IOExceptionc(e);
}
}
......@@ -52,7 +53,7 @@ public class FileUtilc {
try {
return IOUtilc.toString(ClassLoader.getSystemResourceAsStream(path));
} catch (NullPointerException e) {
throw new IoException(new FileNotFoundException("Classpath file does not exist: " + path));
throw new IOExceptionc(new FileNotFoundException("Classpath file does not exist: " + path));
}
}
......
......@@ -2,6 +2,7 @@ package org.rajivprab.cava;
import com.google.common.base.Charsets;
import org.apache.commons.io.IOUtils;
import org.rajivprab.cava.exception.IOExceptionc;
import java.io.IOException;
import java.io.InputStream;
......@@ -20,7 +21,7 @@ public class IOUtilc {
try {
return IOUtils.toString(inputStream, CHARSET_USED);
} catch (IOException e) {
throw new IoException(e);
throw new IOExceptionc(e);
}
}
......@@ -28,13 +29,7 @@ public class IOUtilc {
try {
return IOUtils.readLines(inputStream, CHARSET_USED);
} catch (IOException e) {
throw new IoException(e);
}
}
public static class IoException extends CheckedExceptionWrapper {
public IoException(IOException e) {
super(e);
throw new IOExceptionc(e);
}
}
}
......@@ -3,6 +3,7 @@ package org.rajivprab.cava;
import com.google.common.cache.Cache;
import com.google.common.collect.Maps;
import com.google.common.util.concurrent.UncheckedExecutionException;
import org.rajivprab.cava.exception.CheckedExceptionWrapper;
import java.util.HashMap;
import java.util.concurrent.Callable;
......
......@@ -2,7 +2,8 @@ package org.rajivprab.cava;
import com.google.common.collect.Lists;
import org.json.JSONObject;
import org.rajivprab.cava.IOUtilc.IoException;
import org.rajivprab.cava.exception.IOExceptionc;
import org.rajivprab.cava.exception.SQLExceptionc;
import java.io.IOException;
import java.io.OutputStream;
......@@ -26,7 +27,7 @@ public class PreparedStatementc {
try {
return parseResults(getPreparedStatement(connection, query, args).executeQuery());
} catch (SQLException e) {
throw new SqlException(e);
throw new SQLExceptionc(e);
}
}
......@@ -35,7 +36,7 @@ public class PreparedStatementc {
try {
parseResults(getPreparedStatement(connection, query, args).executeQuery(), outputStream);
} catch (SQLException e) {
throw new SqlException(e);
throw new SQLExceptionc(e);
}
}
......@@ -46,7 +47,7 @@ public class PreparedStatementc {
try {
return getPreparedStatement(connection, query, args).executeUpdate();
} catch (SQLException e) {
throw new SqlException(e);
throw new SQLExceptionc(e);
}
}
......@@ -58,7 +59,7 @@ public class PreparedStatementc {
}
return statement;
} catch (SQLException e) {
throw new SqlException(e);
throw new SQLExceptionc(e);
}
}
......@@ -71,7 +72,7 @@ public class PreparedStatementc {
}
return results;
} catch (SQLException e) {
throw new SqlException(e);
throw new SQLExceptionc(e);
}
}
......@@ -84,9 +85,9 @@ public class PreparedStatementc {
}
outputStream.flush();
} catch (IOException e) {
throw new IoException(e);
throw new IOExceptionc(e);
} catch (SQLException e) {
throw new SqlException(e);
throw new SQLExceptionc(e);
}
}
......@@ -99,7 +100,7 @@ public class PreparedStatementc {
}
return columnNames;
} catch (SQLException e) {
throw new SqlException(e);
throw new SQLExceptionc(e);
}
}
......@@ -112,13 +113,7 @@ public class PreparedStatementc {
}
return entry;
} catch (SQLException e) {
throw new SqlException(e);
}
}
public static class SqlException extends CheckedExceptionWrapper {
public SqlException(SQLException e) {
super(e);
throw new SQLExceptionc(e);
}
}
}
package org.rajivprab.cava;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.rajivprab.cava.exception.CheckedExceptionWrapper;
import org.rajivprab.cava.exception.ExecutionExceptionc;
import org.rajivprab.cava.exception.InterruptedExceptionc;
import org.rajivprab.cava.exception.TimeoutExceptionc;
import java.time.Duration;
import java.util.concurrent.*;
......@@ -12,8 +14,6 @@ import java.util.concurrent.*;
* Created by rprabhakar on 12/15/15.
*/
public class ThreadUtilc {
private static final Logger log = LogManager.getLogger(ThreadUtilc.class);
// ---------- Sleep ------------
public static void sleep(Duration duration) {
......@@ -24,7 +24,7 @@ public class ThreadUtilc {
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
throw new InterruptException(e);
throw new InterruptedExceptionc(e);
}
}
......@@ -43,6 +43,16 @@ public class ThreadUtilc {
// ---------- Get ------------
public static <T> T call(Callable<T> callable) {
try {
return callable.call();
} catch (RuntimeException e) {
throw e;
} catch (Exception e) {
throw new CheckedExceptionWrapper(e);
}
}
public static <T> T get(Future<T> future) {
return get(future, Duration.ofDays(100000));
}
......@@ -58,33 +68,13 @@ public class ThreadUtilc {
try {
return future.get(duration.toNanos(), TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
throw new InterruptException(e);
throw new InterruptedExceptionc(e);
} catch (TimeoutException e) {
throw new TimeException(e);
throw new TimeoutExceptionc(e);
} catch (ExecutionException e) {
// Do not simply throw the cause, because that lacks the stack-trace for this get-method
// Do not wrap e.cause inside CheckedExceptionWrapper, because we would still have above problem
throw new ExecException(e);
}
}
// ---------- Exception-Wrappers ------------
public static class ExecException extends CheckedExceptionWrapper {
public ExecException(ExecutionException e) {
super(e);
}
}
public static class InterruptException extends CheckedExceptionWrapper {
public InterruptException(InterruptedException e) {
super(e);
}
}
public static class TimeException extends CheckedExceptionWrapper {
public TimeException(TimeoutException e) {
super(e);
throw new ExecutionExceptionc(e);
}
}
}
......@@ -5,6 +5,7 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.javatuples.Pair;
import org.javatuples.Triplet;
import org.rajivprab.cava.exception.CheckedExceptionWrapper;
import java.util.Arrays;
import java.util.Collection;
......
package org.rajivprab.cava;
package org.rajivprab.cava.exception;
import java.io.PrintStream;
import java.io.PrintWriter;
......@@ -12,56 +12,56 @@ import java.io.PrintWriter;
* Created by rprabhakar on 12/15/15.
*/
public class CheckedExceptionWrapper extends RuntimeException {
private final Throwable e;
private final Throwable underlying;
public CheckedExceptionWrapper(Throwable e) {
this.e = e;
public CheckedExceptionWrapper(Throwable underlying) {
this.underlying = underlying;
}
public Throwable getUnderlying() {
return e;
return underlying;
}
// Returns the underlying exception's cause, not the underlying exception itself
// To get the underlying exception, use getUnderlying()
@Override
public Throwable getCause() {
return e.getCause();
return underlying.getCause();
}
@Override
public String getLocalizedMessage() {
return e.getLocalizedMessage();
return underlying.getLocalizedMessage();
}
@Override
public String getMessage() {
return e.getMessage();
return underlying.getMessage();
}
@Override
public StackTraceElement[] getStackTrace() {
return e.getStackTrace();
return underlying.getStackTrace();
}
@Override
public void printStackTrace() {
e.printStackTrace();
underlying.printStackTrace();
}
@Override
public void printStackTrace(PrintStream s) {
e.printStackTrace(s);
underlying.printStackTrace(s);
}
@Override
public void printStackTrace(PrintWriter s) {
e.printStackTrace(s);
underlying.printStackTrace(s);
}
@Override
public String toString() {
return getClass().getCanonicalName() + ": " + e.toString();
return getClass().getCanonicalName() + ": " + underlying.toString();
}
@Override
......@@ -77,6 +77,6 @@ public class CheckedExceptionWrapper extends RuntimeException {
@Override
public int hashCode() {
return e.hashCode();
return underlying.hashCode();
}
}
package org.rajivprab.cava.exception;
import java.util.concurrent.ExecutionException;
public class ExecutionExceptionc extends CheckedExceptionWrapper {
public ExecutionExceptionc(ExecutionException e) {
super(e);
}
}
package org.rajivprab.cava.exception;
import java.io.IOException;
public class IOExceptionc extends CheckedExceptionWrapper {
public IOExceptionc(IOException e) {
super(e);
}
}
package org.rajivprab.cava.exception;
public class InterruptedExceptionc extends CheckedExceptionWrapper {
public InterruptedExceptionc(InterruptedException e) {
super(e);
}
}
package org.rajivprab.cava.exception;
import java.sql.SQLException;
public class SQLExceptionc extends CheckedExceptionWrapper {
public SQLExceptionc(SQLException e) {
super(e);
}
}
package org.rajivprab.cava.exception;
import java.util.concurrent.TimeoutException;
public class TimeoutExceptionc extends CheckedExceptionWrapper {
public TimeoutExceptionc(TimeoutException e) {
super(e);
}
}
......@@ -3,7 +3,7 @@ package org.rajivprab.cava;
import com.google.common.truth.Truth;
import org.junit.Assert;
import org.junit.Test;
import org.rajivprab.cava.IOUtilc.IoException;
import org.rajivprab.cava.exception.IOExceptionc;
import java.io.File;
import java.io.FileWriter;
......@@ -37,7 +37,7 @@ public class FileUtilcTest extends TestBase {
try {
FileUtilc.readClasspathFile("not_found.txt");
Assert.fail();
} catch (IoException e) {
} catch (IOExceptionc e) {
Truth.assertThat(e).hasMessageThat().contains("Classpath file does not exist: not_found.txt");
}
}
......@@ -49,7 +49,7 @@ public class FileUtilcTest extends TestBase {
try (Writer writer = new FileWriter(file)) {
writer.write("readSystemFile test");
} catch (IOException e) {
throw new IoException(e);
throw new IOExceptionc(e);
}
Truth.assertThat(FileUtilc.readFileToString(file)).contains("readSystemFile test");
}
......@@ -59,7 +59,7 @@ public class FileUtilcTest extends TestBase {
try {
FileUtilc.readFileToString(new File("/var/tmp/does-not-exist"));
Assert.fail();
} catch (IoException e) {
} catch (IOExceptionc e) {
Truth.assertThat(e).hasMessageThat().contains("File '/var/tmp/does-not-exist' does not exist");
}
}
......
package org.rajivprab.cava;
import com.google.common.truth.Truth;
import org.junit.Assert;
import org.junit.Test;
import org.rajivprab.cava.ThreadUtilc.ExecException;
import org.rajivprab.cava.ThreadUtilc.InterruptException;
import org.rajivprab.cava.ThreadUtilc.TimeException;
import org.rajivprab.cava.exception.CheckedExceptionWrapper;
import org.rajivprab.cava.exception.ExecutionExceptionc;
import org.rajivprab.cava.exception.InterruptedExceptionc;
import org.rajivprab.cava.exception.TimeoutExceptionc;
import java.io.IOException;
import java.time.Duration;
......@@ -17,6 +17,8 @@ import java.util.concurrent.FutureTask;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import static com.google.common.truth.Truth.assertThat;
/**
* Unit tests for ThreadUtil library
* <p>
......@@ -33,7 +35,7 @@ public class ThreadUtilcTest extends TestBase {
public void sleep_allGood() {
checkRunTime(() -> {
int result = ThreadUtilc.get(runSleepTask(TEST_DURATION));
Truth.assertThat(result).isEqualTo(RETURN_VALUE);
assertThat(result).isEqualTo(RETURN_VALUE);
}, TEST_DURATION);
}
......@@ -56,8 +58,8 @@ public class ThreadUtilcTest extends TestBase {
Assert.fail("This will never happen. " +
"InterruptedException is converted into ExecutionException for current-thread");
} catch (ExecutionException e) {
Truth.assertThat(e.getCause()).isInstanceOf(InterruptException.class);
Truth.assertThat(((InterruptException) e.getCause()).getUnderlying()).isInstanceOf(InterruptedException.class);
assertThat(e.getCause()).isInstanceOf(InterruptedExceptionc.class);
assertThat(((InterruptedExceptionc) e.getCause()).getUnderlying()).isInstanceOf(InterruptedException.class);
}
}
......@@ -70,13 +72,41 @@ public class ThreadUtilcTest extends TestBase {
try {
ThreadUtilc.get(taskA);
Assert.fail();
} catch (InterruptException e) {
} catch (InterruptedExceptionc e) {
Assert.fail("This will never happen. " +
"InterruptException is converted into ExecException for current-thread");
} catch (ExecException e) {
Truth.assertThat(e.getUnderlying()).isInstanceOf(ExecutionException.class);
Truth.assertThat(e.getCause()).isInstanceOf(InterruptException.class);
Truth.assertThat(((InterruptException) e.getCause()).getUnderlying()).isInstanceOf(InterruptedException.class);
} catch (ExecutionExceptionc e) {
assertThat(e.getUnderlying()).isInstanceOf(ExecutionException.class);
assertThat(e.getCause()).isInstanceOf(InterruptedExceptionc.class);
assertThat(((InterruptedExceptionc) e.getCause()).getUnderlying()).isInstanceOf(InterruptedException.class);
}
}
// ------------------------ Get -----------------------
@Test
public void call_noErrors() {
assertThat(ThreadUtilc.call(() -> 1)).isEqualTo(1);
}
@Test
public void call_runTimeException_shouldThrowDirectly() {
try {
ThreadUtilc.call(() -> { throw new IllegalStateException("test"); });
Assert.fail();
} catch (IllegalStateException e) {
assertThat(e).hasMessageThat().isEqualTo("test");
}
}
@Test
public void call_checkedException_shouldThrowWithWrapper() {
try {
ThreadUtilc.call(() -> { throw new IOException("test"); });
Assert.fail();
} catch (CheckedExceptionWrapper e) {
assertThat(e.getUnderlying()).isInstanceOf(IOException.class);
assertThat(e).hasMessageThat().isEqualTo("test");
}
}
......@@ -87,7 +117,7 @@ public class ThreadUtilcTest extends TestBase {
Future<Integer> future = runSleepTask(TEST_DURATION);
checkRunTime(() -> {
int result = ThreadUtilc.get(future);
Truth.assertThat(result).isEqualTo(RETURN_VALUE);
assertThat(result).isEqualTo(RETURN_VALUE);
}, TEST_DURATION);
}
......@@ -96,7 +126,7 @@ public class ThreadUtilcTest extends TestBase {
Future<Integer> future = runSleepTask(TEST_DURATION);
checkRunTime(() -> {
int result = threadUtilcGet(future, TEST_DURATION.multipliedBy(2));
Truth.assertThat(result).isEqualTo(RETURN_VALUE);
assertThat(result).isEqualTo(RETURN_VALUE);
}, TEST_DURATION);
}
......@@ -107,7 +137,7 @@ public class ThreadUtilcTest extends TestBase {
try {
threadUtilcGet(future, TEST_DURATION);
Assert.fail("Should have hit timeout");
} catch (TimeException ignored) {
} catch (TimeoutExceptionc ignored) {
}
}, TEST_DURATION);
}
......@@ -119,12 +149,12 @@ public class ThreadUtilcTest extends TestBase {
try {
ThreadUtilc.get(future);
Assert.fail("Exception should have been thrown");
} catch (ExecException e) {
Truth.assertThat(e.getUnderlying()).isInstanceOf(ExecutionException.class);
Truth.assertThat(e.getUnderlying().getCause()).isInstanceOf(IOException.class);
Truth.assertThat(e.getCause()).isInstanceOf(IOException.class);
Truth.assertThat(e).hasMessageThat().isEqualTo("java.io.IOException: test");
Truth.assertThat(e.toString()).matches(".*ExecException: .*ExecutionException: .*IOException: test");
} catch (ExecutionExceptionc e) {
assertThat(e.getUnderlying()).isInstanceOf(ExecutionException.class);
assertThat(e.getUnderlying().getCause()).isInstanceOf(IOException.class);
assertThat(e.getCause()).isInstanceOf(IOException.class);
assertThat(e).hasMessageThat().isEqualTo("java.io.IOException: test");
assertThat(e.toString()).matches(".*ExecutionExceptionc: .*ExecutionException: .*IOException: test");
}
}
......@@ -135,12 +165,12 @@ public class ThreadUtilcTest extends TestBase {
try {
ThreadUtilc.get(future);
Assert.fail("Exception should have been thrown");
} catch (ExecException e) {
Truth.assertThat(e.getUnderlying()).isInstanceOf(ExecutionException.class);
Truth.assertThat(e.getCause()).isInstanceOf(ArithmeticException.class);
Truth.assertThat(e).hasMessageThat().isEqualTo("java.lang.ArithmeticException: test");
Truth.assertThat(e.toString())
.matches(".*ExecException: .*ExecutionException: .*ArithmeticException: test");
} catch (ExecutionExceptionc e) {
assertThat(e.getUnderlying()).isInstanceOf(ExecutionException.class);
assertThat(e.getCause()).isInstanceOf(ArithmeticException.class);
assertThat(e).hasMessageThat().isEqualTo("java.lang.ArithmeticException: test");
assertThat(e.toString())