Skip to content

Commit f14cf33

Browse files
Update Gradle Plugins to its latest versions
Let Parser timeout after 6 seconds and fail gently Add a special test verifying the clean up after timeout
1 parent cdc56c7 commit f14cf33

84 files changed

Lines changed: 423 additions & 114 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

build.gradle

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
plugins {
22
id 'java'
33
id 'maven-publish'
4-
id "ca.coglinc2.javacc" version "3.0.0"
4+
id "ca.coglinc2.javacc" version "latest.release"
55
id 'jacoco'
6-
id "com.github.spotbugs" version "4.7.2"
6+
id "com.github.spotbugs" version "latest.release"
77
id 'pmd'
88
id 'checkstyle'
99

1010
// download the RR tools which have no Maven Repository
11-
id "de.undercouch.download" version "4.1.2"
11+
id "de.undercouch.download" version "latest.release"
1212
}
1313

1414
group = 'com.github.jsqlparser'
@@ -46,13 +46,6 @@ dependencies {
4646

4747
// enforce latest version of JavaCC
4848
javacc 'net.java.dev.javacc:javacc:7.0.10'
49-
50-
// https://mvnrepository.com/artifact/org.mockito/mockito-junit-jupiter
51-
testImplementation 'org.mockito:mockito-junit-jupiter:4.1.0'
52-
53-
// enforce latest version of JavaCC
54-
javacc 'net.java.dev.javacc:javacc:7.0.10'
55-
5649
}
5750

5851
compileJavacc {
@@ -179,7 +172,7 @@ spotbugs {
179172

180173
pmd {
181174
consoleOutput = false
182-
toolVersion = "6.36.0"
175+
toolVersion = "6.41.0"
183176

184177
sourceSets = [sourceSets.main]
185178

@@ -198,7 +191,7 @@ pmd {
198191
}
199192

200193
checkstyle {
201-
toolVersion "8.45.1"
194+
toolVersion "9.2"
202195
sourceSets = [sourceSets.main, sourceSets.test]
203196
configFile =rootProject.file('config/checkstyle/checkstyle.xml')
204197
}

ruleset.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ under the License.
103103
<rule ref="category/java/errorprone.xml/UselessOperationOnImmutable" />
104104

105105
<!-- for Codazy -->
106-
<rule ref="category/java/errorprone.xml/MissingBreakInSwitch" />
106+
<!-- <rule ref="category/java/errorprone.xml/MissingBreakInSwitch" /> -->
107107

108108
<rule ref="category/java/multithreading.xml/AvoidThreadGroup" />
109109
<rule ref="category/java/multithreading.xml/DontCallThreadRun" />

src/main/java/net/sf/jsqlparser/parser/CCJSqlParserUtil.java

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212
import java.io.IOException;
1313
import java.io.InputStream;
1414
import java.io.Reader;
15+
import java.util.concurrent.Callable;
16+
import java.util.concurrent.ExecutorService;
17+
import java.util.concurrent.Executors;
18+
import java.util.concurrent.Future;
19+
import java.util.concurrent.TimeUnit;
20+
import java.util.concurrent.TimeoutException;
1521
import java.util.function.Consumer;
1622
import net.sf.jsqlparser.JSQLParserException;
1723
import net.sf.jsqlparser.expression.Expression;
@@ -23,8 +29,11 @@
2329
*
2430
* @author toben
2531
*/
32+
33+
@SuppressWarnings("PMD.CyclomaticComplexity")
2634
public final class CCJSqlParserUtil {
2735
public final static int ALLOWED_NESTING_DEPTH = 10;
36+
public static final int PARSER_TIMEOUT = 6000;
2837

2938
private CCJSqlParserUtil() {
3039
}
@@ -235,11 +244,25 @@ public static Expression parseCondExpression(String conditionalExpressionStr, bo
235244
* @throws JSQLParserException
236245
*/
237246
public static Statement parseStatement(CCJSqlParser parser) throws JSQLParserException {
247+
Statement statement = null;
238248
try {
239-
return parser.Statement();
249+
ExecutorService executorService = Executors.newSingleThreadExecutor();
250+
Future<Statement> future = executorService.submit(new Callable<Statement>() {
251+
@Override
252+
public Statement call() throws Exception {
253+
return parser.Statement();
254+
}
255+
});
256+
executorService.shutdown();
257+
258+
statement = future.get(PARSER_TIMEOUT, TimeUnit.MILLISECONDS);
259+
} catch (TimeoutException ex) {
260+
parser.interrupted = true;
261+
throw new JSQLParserException("Time out occurred.", ex);
240262
} catch (Exception ex) {
241263
throw new JSQLParserException(ex);
242264
}
265+
return statement;
243266
}
244267

245268
/**
@@ -270,11 +293,25 @@ public static Statements parseStatements(String sqls) throws JSQLParserException
270293
* @throws JSQLParserException
271294
*/
272295
public static Statements parseStatements(CCJSqlParser parser) throws JSQLParserException {
296+
Statements statements = null;
273297
try {
274-
return parser.Statements();
298+
ExecutorService executorService = Executors.newSingleThreadExecutor();
299+
Future<Statements> future = executorService.submit(new Callable<Statements>() {
300+
@Override
301+
public Statements call() throws Exception {
302+
return parser.Statements();
303+
}
304+
});
305+
executorService.shutdown();
306+
307+
statements = future.get(PARSER_TIMEOUT, TimeUnit.MILLISECONDS);
308+
} catch (TimeoutException ex) {
309+
parser.interrupted = true;
310+
throw new JSQLParserException("Time out occurred.", ex);
275311
} catch (Exception ex) {
276312
throw new JSQLParserException(ex);
277313
}
314+
return statements;
278315
}
279316

280317
public static void streamStatements(StatementListener listener, InputStream is, String encoding) throws JSQLParserException {

src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ import java.util.*;
6969
public class CCJSqlParser extends AbstractJSqlParser<CCJSqlParser> {
7070
public int bracketsCounter = 0;
7171
public int caseCounter = 0;
72+
public boolean interrupted = false;
7273

7374
public CCJSqlParser withConfiguration(FeatureConfiguration configuration) {
7475
token_source.configuration = configuration;
@@ -3296,7 +3297,7 @@ ExpressionList SimpleExpressionList(boolean outerBrackets) #ExpressionList:
32963297
}
32973298
{
32983299
expr=SimpleExpression() { expressions.add(expr); }
3299-
( LOOKAHEAD(2) "," expr=SimpleExpression() { expressions.add(expr); } )*
3300+
( LOOKAHEAD(2, {!interrupted} ) "," expr=SimpleExpression() { expressions.add(expr); } )*
33003301
{
33013302
retval.setExpressions(expressions);
33023303
return retval;
@@ -3316,7 +3317,7 @@ ExpressionList ComplexExpressionList() #ExpressionList:
33163317
) { expressions.add(expr); }
33173318

33183319
(
3319-
LOOKAHEAD(2) ","
3320+
LOOKAHEAD(2, {!interrupted}) ","
33203321
(
33213322
LOOKAHEAD(2) expr=OracleNamedFunctionParameter()
33223323
| expr=Expression()
@@ -3657,62 +3658,62 @@ Expression PrimaryExpression() #PrimaryExpression:
36573658
(
36583659
<K_NULL> { retval = new NullValue(); }
36593660

3660-
| LOOKAHEAD(3) retval=CaseWhenExpression()
3661+
| LOOKAHEAD(3, {!interrupted}) retval=CaseWhenExpression()
36613662

36623663
| retval = SimpleJdbcParameter()
36633664

3664-
| LOOKAHEAD(2) retval=JdbcNamedParameter()
3665+
| LOOKAHEAD(2, {!interrupted}) retval=JdbcNamedParameter()
36653666

36663667
| retval=UserVariable()
36673668

3668-
| LOOKAHEAD(2) retval=NumericBind()
3669+
| LOOKAHEAD(2, {!interrupted}) retval=NumericBind()
36693670

3670-
| LOOKAHEAD(3) retval=ExtractExpression()
3671+
| LOOKAHEAD(3, {!interrupted}) retval=ExtractExpression()
36713672

36723673
| retval=MySQLGroupConcat()
36733674

36743675
| retval=XMLSerializeExpr()
36753676

3676-
| LOOKAHEAD(JsonExpression()) retval=JsonExpression()
3677+
| LOOKAHEAD(JsonExpression(), {!interrupted}) retval=JsonExpression()
36773678

3678-
| LOOKAHEAD(JsonFunction()) retval = JsonFunction()
3679+
| LOOKAHEAD(JsonFunction(), {!interrupted}) retval = JsonFunction()
36793680

3680-
| LOOKAHEAD(JsonAggregateFunction()) retval = JsonAggregateFunction()
3681+
| LOOKAHEAD(JsonAggregateFunction(), {!interrupted}) retval = JsonAggregateFunction()
36813682

36823683
/* | LOOKAHEAD(FunctionWithCondParams()) retval = FunctionWithCondParams() */
36833684

3684-
| LOOKAHEAD(FullTextSearch()) retval = FullTextSearch()
3685+
| LOOKAHEAD(FullTextSearch(), {!interrupted}) retval = FullTextSearch()
36853686

3686-
| LOOKAHEAD(Function()) retval=Function() [ LOOKAHEAD(2) retval = AnalyticExpression( (Function) retval ) ]
3687+
| LOOKAHEAD(Function(), {!interrupted}) retval=Function() [ LOOKAHEAD(2) retval = AnalyticExpression( (Function) retval ) ]
36873688

3688-
| LOOKAHEAD(2) retval = IntervalExpression() { dateExpressionAllowed = false; }
3689+
| LOOKAHEAD(2, {!interrupted}) retval = IntervalExpression() { dateExpressionAllowed = false; }
36893690

36903691
| token=<S_DOUBLE> { retval = new DoubleValue(token.image); }
36913692

36923693
| token=<S_LONG> { retval = new LongValue(token.image); }
36933694

36943695
| token=<S_HEX> { retval = new HexValue(token.image); }
36953696

3696-
| LOOKAHEAD(2) retval=CastExpression()
3697+
| LOOKAHEAD(2, {!interrupted}) retval=CastExpression()
36973698

3698-
| LOOKAHEAD(2) retval=TryCastExpression()
3699+
| LOOKAHEAD(2, {!interrupted}) retval=TryCastExpression()
36993700

37003701
//| LOOKAHEAD(2) retval=RowConstructor()
37013702

37023703
// support timestamp expressions
37033704
| (token=<K_TIME_KEY_EXPR> | token=<K_CURRENT>) { retval = new TimeKeyExpression(token.image); }
37043705

3705-
| LOOKAHEAD(2) retval=DateTimeLiteralExpression()
3706+
| LOOKAHEAD(2, {!interrupted}) retval=DateTimeLiteralExpression()
37063707

3707-
| LOOKAHEAD(2) <K_ARRAY_LITERAL> retval=ArrayConstructor(true)
3708+
| LOOKAHEAD(2, {!interrupted}) <K_ARRAY_LITERAL> retval=ArrayConstructor(true)
37083709

3709-
| LOOKAHEAD(2) retval = NextValExpression()
3710+
| LOOKAHEAD(2, {!interrupted}) retval = NextValExpression()
37103711

37113712
| retval=ConnectByRootOperator()
37123713

3713-
| LOOKAHEAD(2) <K_ALL> { retval = new AllValue(); }
3714+
| LOOKAHEAD(2, {!interrupted}) <K_ALL> { retval = new AllValue(); }
37143715

3715-
| LOOKAHEAD(2) retval=Column()
3716+
| LOOKAHEAD(2, {!interrupted}) retval=Column()
37163717

37173718
| token=<S_CHAR_LITERAL> { retval = new StringValue(token.image); linkAST(retval,jjtThis); }
37183719

@@ -3722,10 +3723,10 @@ Expression PrimaryExpression() #PrimaryExpression:
37223723

37233724
| "{ts" token=<S_CHAR_LITERAL> "}" { retval = new TimestampValue(token.image); }
37243725

3725-
| LOOKAHEAD("(" retval=SubSelect() ")") "(" retval=SubSelect() ")"
3726+
| LOOKAHEAD("(" retval=SubSelect() ")", {!interrupted} ) "(" retval=SubSelect() ")"
37263727

37273728
| (
3728-
"(" ( LOOKAHEAD( { getAsBoolean(Feature.allowComplexParsing) } ) list = ComplexExpressionList() | list = SimpleExpressionList(true) ) ")"
3729+
"(" ( LOOKAHEAD( { getAsBoolean(Feature.allowComplexParsing) && !interrupted } ) list = ComplexExpressionList() | list = SimpleExpressionList(true) ) ")"
37293730
{
37303731
if (list.getExpressions().size() == 1) {
37313732
retval = new Parenthesis(list.getExpressions().get(0));

src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,11 @@
1515
import java.util.ArrayList;
1616
import java.util.Collections;
1717
import java.util.List;
18+
import java.util.concurrent.ExecutorService;
19+
import java.util.concurrent.Executors;
20+
import java.util.concurrent.TimeUnit;
1821

22+
import net.sf.jsqlparser.parser.CCJSqlParser;
1923
import net.sf.jsqlparser.JSQLParserException;
2024
import net.sf.jsqlparser.expression.*;
2125
import net.sf.jsqlparser.expression.operators.arithmetic.Addition;
@@ -36,6 +40,8 @@
3640
import net.sf.jsqlparser.statement.StatementVisitorAdapter;
3741
import net.sf.jsqlparser.statement.Statements;
3842
import static net.sf.jsqlparser.test.TestUtils.*;
43+
44+
import net.sf.jsqlparser.test.MemoryLeakVerifier;
3945
import org.apache.commons.io.IOUtils;
4046
import static org.assertj.core.api.Assertions.assertThat;
4147
import static org.junit.jupiter.api.Assertions.assertEquals;
@@ -45,9 +51,11 @@
4551
import static org.junit.jupiter.api.Assertions.assertTrue;
4652
import static org.junit.jupiter.api.Assertions.fail;
4753

54+
import org.junit.jupiter.api.Assertions;
4855
import org.junit.jupiter.api.Disabled;
4956
import org.junit.jupiter.api.Test;
5057
import org.junit.jupiter.api.Timeout;
58+
import org.junit.jupiter.api.function.Executable;
5159
import org.junit.jupiter.api.parallel.Execution;
5260
import org.junit.jupiter.api.parallel.ExecutionMode;
5361

@@ -5028,4 +5036,86 @@ public void testPerformanceIssue1397() throws Exception {
50285036
String sqlStr = IOUtils.toString( SelectTest.class.getResource( "/net/sf/jsqlparser/statement/select/performanceIssue1397.sql" ), Charset.defaultCharset() );
50295037
assertSqlCanBeParsedAndDeparsed(sqlStr, true);
50305038
}
5039+
5040+
/**
5041+
* The purpose of the test is to run into a timeout and to stop the parser when this happens.
5042+
* We provide an INVALID statement for this purpose, which will fail the SIMPLE parse
5043+
* and then hang with COMPLEX parsing until the timeout occurs.
5044+
*
5045+
* We repeat that test multiple times and want to see no stale references to the Parser after timeout.
5046+
*
5047+
* @throws JSQLParserException
5048+
*/
5049+
@Test
5050+
public void testParserInterruptedByTimeout() {
5051+
String sqlStr = "" +
5052+
"SELECT \t* FROM TABLE_1 t1\n" +
5053+
"WHERE\n" +
5054+
"\t(((t1.COL1 = 'VALUE2' )\n" +
5055+
"\t\tAND (t1.CAL2 = 'VALUE2' ))\n" +
5056+
"\t\tAND (((1 = 1 )\n" +
5057+
"\t\t\tAND ((((((t1.id IN (940550 ,940600 ,940650 ,940700 ,940750 ,940800 ,940850 ,940900 ,940950 ,941000 ,941050 ,941100 ,941150 ,941200 ,941250 ,941300 ,941350 ,941400 ,941450 ,941500 ,941550 ,941600 ,941650 ,941700 ,941750 ,941800 ,941850 ,941900 ,941950 ,942000 ,942050 ,942100 ,942150 ,942200 ,942250 ,942300 ,942350 ,942400 ,942450 ,942500 ,942550 ,942600 ,942650 ,942700 ,942750 ,942800 ,942850 ,942900 ,942950 ,943000 ,943050 ,943100 ,943150 ,943200 ,943250 ,943300 ,943350 ,943400 ,943450 ,943500 ,943550 ,943600 ,943650 ,943700 ,943750 ,943800 ,943850 ,943900 ,943950 ,944000 ,944050 ,944100 ,944150 ,944200 ,944250 ,944300 ,944350 ,944400 ,944450 ,944500 ,944550 ,944600 ,944650 ,944700 ,944750 ,944800 ,944850 ,944900 ,944950 ,945000 ,945050 ,945100 ,945150 ,945200 ,945250 ,945300 ))\n" +
5058+
"\t\t\t\tOR (t1.id IN (945350 ,945400 ,945450 ,945500 ,945550 ,945600 ,945650 ,945700 ,945750 ,945800 ,945850 ,945900 ,945950 ,946000 ,946050 ,946100 ,946150 ,946200 ,946250 ,946300 ,946350 ,946400 ,946450 ,946500 ,946550 ,946600 ,946650 ,946700 ,946750 ,946800 ,946850 ,946900 ,946950 ,947000 ,947050 ,947100 ,947150 ,947200 ,947250 ,947300 ,947350 ,947400 ,947450 ,947500 ,947550 ,947600 ,947650 ,947700 ,947750 ,947800 ,947850 ,947900 ,947950 ,948000 ,948050 ,948100 ,948150 ,948200 ,948250 ,948300 ,948350 ,948400 ,948450 ,948500 ,948550 ,948600 ,948650 ,948700 ,948750 ,948800 ,948850 ,948900 ,948950 ,949000 ,949050 ,949100 ,949150 ,949200 ,949250 ,949300 ,949350 ,949400 ,949450 ,949500 ,949550 ,949600 ,949650 ,949700 ,949750 ,949800 ,949850 ,949900 ,949950 ,950000 ,950050 ,950100 )))\n" +
5059+
"\t\t\t\tOR (t1.id IN (950150 ,950200 ,950250 ,950300 ,950350 ,950400 ,950450 ,950500 ,950550 ,950600 ,950650 ,950700 ,950750 ,950800 ,950850 ,950900 ,950950 ,951000 ,951050 ,951100 ,951150 ,951200 ,951250 ,951300 ,951350 ,951400 ,951450 ,951500 ,951550 ,951600 ,951650 ,951700 ,951750 ,951800 ,951850 ,951900 ,951950 ,952000 ,952050 ,952100 ,952150 ,952200 ,952250 ,952300 ,952350 ,952400 ,952450 ,952500 ,952550 ,952600 ,952650 ,952700 ,952750 ,952800 ,952850 ,952900 ,952950 ,953000 ,953050 ,953100 ,953150 ,953200 ,953250 ,953300 ,953350 ,953400 ,953450 ,953500 ,953550 ,953600 ,953650 ,953700 )))\n" +
5060+
"\t\t\t\tOR (t1.id IN (953750 ,953800 ,953850 ,953900 ,953950 ,954000 ,954050 ,954100 ,954150 ,954200 ,954250 ,954300 ,954350 ,954400 ,954450 ,954500 ,954550 ,954600 ,954650 ,954700 ,954750 ,954800 ,954850 ,954900 ,954950 ,955000 ,955050 ,955100 ,955150 ,955200 ,955250 ,955300 ,955350 ,955400 ,955450 ,955500 ,955550 ,955600 ,955650 ,955700 ,955750 ,955800 ,955850 ,955900 ,955950 ,956000 ,956050 ,956100 ,956150 ,956200 ,956250 ,956300 ,956350 ,956400 ,956450 ,956500 ,956550 ,956600 ,956650 ,956700 ,956750 ,956800 ,956850 ,956900 ,956950 ,957000 ,957050 ,957100 ,957150 ,957200 ,957250 ,957300 )))\n" +
5061+
"\t\t\t\tOR (t1.id IN (944100, 944150, 944200, 944250, 944300, 944350, 944400, 944450, 944500, 944550, 944600, 944650, 944700, 944750, 944800, 944850, 944900, 944950, 945000 )))\n" +
5062+
"\t\t\t\tOR (t1.id IN (957350 ,957400 ,957450 ,957500 ,957550 ,957600 ,957650 ,957700 ,957750 ,957800 ,957850 ,957900 ,957950 ,958000 ,958050 ,958100 ,958150 ,958200 ,958250 ,958300 ,958350 ,958400 ,958450 ,958500 ,958550 ,958600 ,958650 ,958700 ,958750 ,958800 ,958850 ,958900 ,958950 ,959000 ,959050 ,959100 ,959150 ,959200 ,959250 ,959300 ,959350 ,959400 ,959450 ,959500 ,959550 ,959600 ,959650 ,959700 ,959750 ,959800 ,959850 ,959900 ,959950 ,960000 ,960050 ,960100 ,960150 ,960200 ,960250 ,960300 ,960350 ,960400 ,960450 ,960500 ,960550 ,960600 ,960650 ,960700 ,960750 ,960800 ,960850 ,960900 ,960950 ,961000 ,961050 ,961100 ,961150 ,961200 ,961250 ,961300 ,961350 ,961400 ,961450 ,961500 ,961550 ,961600 ,961650 ,961700 ,961750 ,961800 ,961850 ,961900 ,961950 ,962000 ,962050 ,962100 ))))\n" +
5063+
"\t\t\t\tOR (t1.id IN (962150 ,962200 ,962250 ,962300 ,962350 ,962400 ,962450 ,962500 ,962550 ,962600 ,962650 ,962700 ,962750 ,962800 ,962850 ,962900 ,962950 ,963000 ,963050 ,963100 ,963150 ,963200 ,963250 ,963300 ,963350 ,963400 ,963450 ,963500 ,963550 ,963600 ,963650 ,963700 ,963750 ,963800 ,963850 ,963900 ,963950 ,964000 ,964050 ,964100 ,964150 ,964200 ,964250 ,964300 ,964350 ,964400 ,964450 ,964500 ,964550 ,964600 ,964650 ,964700 ,964750 ,964800 ,964850 ,964900 ,964950 ,965000 ,965050 ,965100 ,965150 ,965200 ,965250 ,965300 ,965350 ,965400 ,965450 ,965500 ))))\n" +
5064+
"\tAND t1.COL3 IN (\n" +
5065+
"\t SELECT\n" +
5066+
"\t\t t2.COL3\n" +
5067+
"\t FROM\n" +
5068+
"\t\t TABLE_6 t6,\n" +
5069+
"\t\t TABLE_1 t5,\n" +
5070+
"\t\t TABLE_4 t4,\n" +
5071+
"\t\t TABLE_3 t3,\n" +
5072+
"\t\t TABLE_1 t2\n" +
5073+
"\t WHERE\n" +
5074+
"\t\t (((((((t5.CAL3 = T6.id)\n" +
5075+
"\t\t\t AND (t5.CAL5 = t6.CAL5))\n" +
5076+
"\t\t\t AND (t5.CAL1 = t6.CAL1))\n" +
5077+
"\t\t\t AND (t3.CAL1 IN (108500)))\n" +
5078+
"\t\t\t AND (t5.id = t2.id))\n" +
5079+
"\t\t\t AND NOT ((t6.CAL6 IN ('VALUE'))))\n" +
5080+
"\t\t\t AND ((t2.id = t3.CAL2)\n" +
5081+
"\t\t\t\t AND (t4.id = t3.CAL3))))\n" +
5082+
// add two redundant unmatched brackets in order to make the Simple Parser fail
5083+
// and the complex parser stuck
5084+
" )) \n" +
5085+
"ORDER BY\n" +
5086+
"\tt1.id ASC";
5087+
5088+
MemoryLeakVerifier verifier = new MemoryLeakVerifier();
5089+
5090+
int parallelThreads = Runtime.getRuntime().availableProcessors() + 1;
5091+
ExecutorService executorService = Executors.newFixedThreadPool(parallelThreads);
5092+
5093+
for (int i=0; i<parallelThreads; i++) {
5094+
executorService.submit(new Runnable() {
5095+
@Override
5096+
public void run() {
5097+
try {
5098+
CCJSqlParser parser = CCJSqlParserUtil.newParser(sqlStr).withAllowComplexParsing(true);
5099+
verifier.addObject(parser);
5100+
5101+
Statement statement = CCJSqlParserUtil.parseStatement(parser);
5102+
} catch (JSQLParserException ignore) {
5103+
// We expected that to happen.
5104+
}
5105+
}
5106+
});
5107+
}
5108+
executorService.shutdown();
5109+
5110+
// we should not run in any timeout here (because we expect that the Parser has timed out by itself)
5111+
Assertions.assertDoesNotThrow(new Executable() {
5112+
@Override
5113+
public void execute() throws Throwable {
5114+
executorService.awaitTermination(10, TimeUnit.SECONDS);
5115+
}
5116+
});
5117+
5118+
// we should not have any Objects left in the weak reference map
5119+
verifier.assertGarbageCollected();
5120+
}
50315121
}

0 commit comments

Comments
 (0)