Skip to content

Commit

Permalink
General coding rule to detect usages of old time and date classes (#1384
Browse files Browse the repository at this point in the history
 / #1385)

With this commit new general rules are added which detect the usages of old
time and date classes, e.g. java.util.Date.

closes #1384

> Developer's Certificate of Origin 1.1
>
> By making a contribution to this project, I certify that:
>
> (a) The contribution was created in whole or in part by me and I
>     have the right to submit it under the open source license
>     indicated in the file; or
>
> (b) The contribution is based upon previous work that, to the best
>     of my knowledge, is covered under an appropriate open source
>     license and I have the right under that license to submit that
>     work with modifications, whether created in whole or in part
>     by me, under the same open source license (unless I am
>     permitted to submit under a different license), as indicated
>     in the file; or
>
> (c) The contribution was provided directly to me by some other
>     person who certified (a), (b) or (c) and I have not modified
>     it.
>
> (d) I understand and agree that this project and the contribution
>     are public and that a record of the contribution (including all
>     personal information I submit with it, including my sign-off) is
>     maintained indefinitely and may be redistributed consistent with
>     this project or the open source license(s) involved.

Signed-off-by: Matthias Bünger <[email protected]>
  • Loading branch information
Bukama committed Jan 25, 2025
1 parent 2d80ef6 commit 1eab59d
Show file tree
Hide file tree
Showing 7 changed files with 113 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -509,4 +509,18 @@ public void check(JavaClass implementationClass, ConditionEvents events) {
.should(accessTargetWhere(JavaAccess.Predicates.target(annotatedWith(Deprecated.class))).as("access @Deprecated members"))
.orShould(dependOnClassesThat(annotatedWith(Deprecated.class)).as("depend on @Deprecated classes"))
.because("there should be a better alternative");

/**
* A rule checking that no classes uses old date and time classes and point out to use the Java 8 time API.
*/
@PublicAPI(usage = ACCESS)
public static final ArchRule OLD_DATE_AND_TIME_CLASSES_SHOULD_NOT_BE_USED =
noClasses()
.should().dependOnClassesThat().haveFullyQualifiedName("java.sql.Date")
.orShould().dependOnClassesThat().haveFullyQualifiedName("java.sql.Time")
.orShould().dependOnClassesThat().haveFullyQualifiedName("java.sql.Timestamp")
.orShould().dependOnClassesThat().haveFullyQualifiedName("java.util.Calendar")
.orShould().dependOnClassesThat().haveFullyQualifiedName("java.util.Date")
.as("since Java 8 (and JavaEE 7 if JPA is needed) java.time-API should be used.")
.because("since Java 8 (and JavaEE 7 if JPA is needed) java.time-API should be used.");
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,17 @@
import com.tngtech.archunit.library.testclasses.packages.incorrect.wrongsubdir.customsuffix.subdir.ImplementationClassWithWrongTestClassPackageCustomSuffixTestingScenario;
import com.tngtech.archunit.library.testclasses.packages.incorrect.wrongsubdir.defaultsuffix.ImplementationClassWithWrongTestClassPackage;
import com.tngtech.archunit.library.testclasses.packages.incorrect.wrongsubdir.defaultsuffix.subdir.ImplementationClassWithWrongTestClassPackageTest;
import com.tngtech.archunit.library.testclasses.timeapi.incorrect.UsesJavaSqlDate;
import com.tngtech.archunit.library.testclasses.timeapi.incorrect.UsesJavaSqlTime;
import com.tngtech.archunit.library.testclasses.timeapi.incorrect.UsesJavaSqlTimestamp;
import com.tngtech.archunit.library.testclasses.timeapi.incorrect.UsesJavaUtilCalender;
import com.tngtech.archunit.library.testclasses.timeapi.incorrect.UsesJavaUtilDate;
import org.junit.Test;

import static com.tngtech.archunit.core.domain.JavaConstructor.CONSTRUCTOR_NAME;
import static com.tngtech.archunit.library.GeneralCodingRules.ASSERTIONS_SHOULD_HAVE_DETAIL_MESSAGE;
import static com.tngtech.archunit.library.GeneralCodingRules.DEPRECATED_API_SHOULD_NOT_BE_USED;
import static com.tngtech.archunit.library.GeneralCodingRules.OLD_DATE_AND_TIME_CLASSES_SHOULD_NOT_BE_USED;
import static com.tngtech.archunit.library.GeneralCodingRules.testClassesShouldResideInTheSamePackageAsImplementation;
import static com.tngtech.archunit.testutil.Assertions.assertThatRule;

Expand Down Expand Up @@ -180,4 +186,46 @@ void origin() {
@SuppressWarnings("DeprecatedIsStillUsed")
private @interface DeprecatedAnnotation {
}



@Test
public void OLD_DATE_AND_TIME_CLASSES_SHOULD_NOT_BE_USED_should_fail_when_class_uses_java_util_date() {
assertThatRule(OLD_DATE_AND_TIME_CLASSES_SHOULD_NOT_BE_USED)
.hasDescriptionContaining("since Java 8 (and JavaEE 7 if JPA is needed) java.time-API should be used.")
.checking(new ClassFileImporter().importClasses(UsesJavaUtilDate.class))
.hasViolationContaining("calls method <java.util.Date");
}

@Test
public void OLD_DATE_AND_TIME_CLASSES_SHOULD_NOT_BE_USED_should_fail_when_class_uses_java_sql_timestamp() {
assertThatRule(OLD_DATE_AND_TIME_CLASSES_SHOULD_NOT_BE_USED)
.hasDescriptionContaining("since Java 8 (and JavaEE 7 if JPA is needed) java.time-API should be used.")
.checking(new ClassFileImporter().importClasses(UsesJavaSqlTimestamp.class))
.hasViolationContaining("calls constructor <java.sql.Timestamp");
}

@Test
public void OLD_DATE_AND_TIME_CLASSES_SHOULD_NOT_BE_USED_should_fail_when_class_uses_java_sql_time() {
assertThatRule(OLD_DATE_AND_TIME_CLASSES_SHOULD_NOT_BE_USED)
.hasDescriptionContaining("since Java 8 (and JavaEE 7 if JPA is needed) java.time-API should be used.")
.checking(new ClassFileImporter().importClasses(UsesJavaSqlTime.class))
.hasViolationContaining("calls constructor <java.sql.Time");
}

@Test
public void OLD_DATE_AND_TIME_CLASSES_SHOULD_NOT_BE_USED_should_fail_when_class_uses_java_sql_date() {
assertThatRule(OLD_DATE_AND_TIME_CLASSES_SHOULD_NOT_BE_USED)
.hasDescriptionContaining("since Java 8 (and JavaEE 7 if JPA is needed) java.time-API should be used.")
.checking(new ClassFileImporter().importClasses(UsesJavaSqlDate.class))
.hasViolationContaining("calls constructor <java.sql.Date");
}

@Test
public void OLD_DATE_AND_TIME_CLASSES_SHOULD_NOT_BE_USED_should_fail_when_class_uses_java_util_calender() {
assertThatRule(OLD_DATE_AND_TIME_CLASSES_SHOULD_NOT_BE_USED)
.hasDescriptionContaining("since Java 8 (and JavaEE 7 if JPA is needed) java.time-API should be used.")
.checking(new ClassFileImporter().importClasses(UsesJavaUtilCalender.class))
.hasViolationContaining("calls method <java.util.Calendar");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.tngtech.archunit.library.testclasses.timeapi.incorrect;

import java.sql.Date;

public class UsesJavaSqlDate {

void usesSqlDate() {
Date badUsage = new Date(System.currentTimeMillis());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.tngtech.archunit.library.testclasses.timeapi.incorrect;

import java.sql.Time;

public class UsesJavaSqlTime {

void usesSqlTimestamp() {
Time badUsage = new Time(System.currentTimeMillis());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.tngtech.archunit.library.testclasses.timeapi.incorrect;

import java.sql.Timestamp;

public class UsesJavaSqlTimestamp {

void usesSqlTimestamp() {
Timestamp badUsage = new Timestamp(System.currentTimeMillis());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package com.tngtech.archunit.library.testclasses.timeapi.incorrect;

import java.util.Calendar;

public class UsesJavaUtilCalender {

void usesJavaUtilCalender() {
Calendar badUsage = Calendar.getInstance();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.tngtech.archunit.library.testclasses.timeapi.incorrect;

import java.time.Instant;
import java.util.Date;

public class UsesJavaUtilDate {

void usesJavaUtilDate() {
Date badDate = Date.from(Instant.now());
}
}

0 comments on commit 1eab59d

Please sign in to comment.