diff --git a/.github/workflows/build-test.yml b/.github/workflows/build-test.yml index 399aed813..79832e6ff 100644 --- a/.github/workflows/build-test.yml +++ b/.github/workflows/build-test.yml @@ -110,6 +110,14 @@ jobs: distribution: temurin java-version: 8 + - name: Install go + uses: actions/setup-go@v5 + with: + go-version: '^1.20' + + - name: Install protoc-gen-go + run: go install google.golang.org/protobuf/cmd/protoc-gen-go@v1.32.0 + - name: Cache Coursier cache uses: coursier/cache-action@v6 diff --git a/benchmark-java/build.sbt b/benchmark-java/build.sbt index 553070185..f4a258035 100644 --- a/benchmark-java/build.sbt +++ b/benchmark-java/build.sbt @@ -14,7 +14,7 @@ run / javaOptions ++= List("-Xms1g", "-Xmx1g", "-XX:+PrintGCDetails", "-XX:+Prin // generate both client and server (default) in Java pekkoGrpcGeneratedLanguages := Seq(PekkoGrpc.Java) -val grpcVersion = "1.54.2" // checked synced by VersionSyncCheckPlugin +val grpcVersion = "1.61.1" // checked synced by VersionSyncCheckPlugin val runtimeProject = ProjectRef(file("../"), "runtime") diff --git a/build.sbt b/build.sbt index bbba57aa0..e910d748d 100644 --- a/build.sbt +++ b/build.sbt @@ -285,6 +285,7 @@ lazy val pluginTesterJava = Project(id = "plugin-tester-java", base = file("plug .settings( name := s"$pekkoPrefix-plugin-tester-java", fork := true, + PB.protocVersion := Dependencies.Versions.googleProtoc, ReflectiveCodeGen.generatedLanguages := Seq("Java"), crossScalaVersions := Dependencies.Versions.CrossScalaForLib, scalaVersion := scala212, diff --git a/codegen/src/main/scala/org/apache/pekko/grpc/gen/ProtocSettings.scala b/codegen/src/main/scala/org/apache/pekko/grpc/gen/ProtocSettings.scala index 00f7dad84..ac97ba2bd 100644 --- a/codegen/src/main/scala/org/apache/pekko/grpc/gen/ProtocSettings.scala +++ b/codegen/src/main/scala/org/apache/pekko/grpc/gen/ProtocSettings.scala @@ -26,5 +26,6 @@ object ProtocSettings { "ascii_format_to_string", "no_lenses", "retain_source_code_info", - "grpc") + "grpc", + "scala3_sources") } diff --git a/codegen/src/main/scala/org/apache/pekko/grpc/gen/scaladsl/ScalaCodeGenerator.scala b/codegen/src/main/scala/org/apache/pekko/grpc/gen/scaladsl/ScalaCodeGenerator.scala index 65a61c0a2..3aa7ea16c 100644 --- a/codegen/src/main/scala/org/apache/pekko/grpc/gen/scaladsl/ScalaCodeGenerator.scala +++ b/codegen/src/main/scala/org/apache/pekko/grpc/gen/scaladsl/ScalaCodeGenerator.scala @@ -99,6 +99,7 @@ abstract class ScalaCodeGenerator extends CodeGenerator { case (p, "no_lenses") => p.copy(lenses = false) case (p, "retain_source_code_info") => p.copy(retainSourceCodeInfo = true) case (p, "grpc") => p.copy(grpc = true) + case (p, "scala3_sources") => p.copy(scala3Sources = true) case (x, _) => x } } diff --git a/codegen/src/main/scala/org/apache/pekko/grpc/gen/scaladsl/ScalaCompatConstants.scala b/codegen/src/main/scala/org/apache/pekko/grpc/gen/scaladsl/ScalaCompatConstants.scala new file mode 100644 index 000000000..1389f3598 --- /dev/null +++ b/codegen/src/main/scala/org/apache/pekko/grpc/gen/scaladsl/ScalaCompatConstants.scala @@ -0,0 +1,23 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.pekko.grpc.gen.scaladsl + +private[scaladsl] class ScalaCompatConstants(emitScala3Sources: Boolean = false) { + // val WildcardType: String = if (emitScala3Sources) "?" else "_" + val WildcardImport: String = if (emitScala3Sources) "*" else "_" +} diff --git a/codegen/src/main/scala/org/apache/pekko/grpc/gen/scaladsl/Service.scala b/codegen/src/main/scala/org/apache/pekko/grpc/gen/scaladsl/Service.scala index 949618075..00fe6f6ee 100644 --- a/codegen/src/main/scala/org/apache/pekko/grpc/gen/scaladsl/Service.scala +++ b/codegen/src/main/scala/org/apache/pekko/grpc/gen/scaladsl/Service.scala @@ -28,7 +28,8 @@ case class Service( serverPowerApi: Boolean, usePlayActions: Boolean, options: com.google.protobuf.DescriptorProtos.ServiceOptions, - comment: Option[String] = None) { + comment: Option[String] = None, + scalaCompatConstants: ScalaCompatConstants) { def serializers: Seq[Serializer] = (methods.map(_.deserializer) ++ methods.map(_.serializer)).distinct def packageDir = packageName.replace('.', '/') } @@ -56,6 +57,7 @@ object Service { serverPowerApi, usePlayActions, serviceDescriptor.getOptions, - serviceDescriptor.comment) + serviceDescriptor.comment, + new ScalaCompatConstants(fileDesc.emitScala3Sources)) } } diff --git a/codegen/src/main/twirl/templates/ScalaClient/Client.scala.txt b/codegen/src/main/twirl/templates/ScalaClient/Client.scala.txt index 312f0e182..e60fc9621 100644 --- a/codegen/src/main/twirl/templates/ScalaClient/Client.scala.txt +++ b/codegen/src/main/twirl/templates/ScalaClient/Client.scala.txt @@ -59,7 +59,7 @@ object @{service.name}Client { new Default@{service.name}Client(channel, isChannelOwned = false) private class Default@{service.name}Client(channel: GrpcChannel, isChannelOwned: Boolean)(implicit sys: ClassicActorSystemProvider) extends @{service.name}Client { - import @{service.name}.MethodDescriptors._ + import @{service.name}.MethodDescriptors.@{service.scalaCompatConstants.WildcardImport} private implicit val ex: ExecutionContext = sys.classicSystem.dispatcher private val settings = channel.settings diff --git a/codegen/src/main/twirl/templates/ScalaCommon/ApiTrait.scala.txt b/codegen/src/main/twirl/templates/ScalaCommon/ApiTrait.scala.txt index 7de502e15..8ec7796c3 100644 --- a/codegen/src/main/twirl/templates/ScalaCommon/ApiTrait.scala.txt +++ b/codegen/src/main/twirl/templates/ScalaCommon/ApiTrait.scala.txt @@ -58,7 +58,7 @@ object @{service.name} extends pekko.grpc.ServiceDescription { object MethodDescriptors { import pekko.grpc.internal.Marshaller import io.grpc.MethodDescriptor - import Serializers._ + import Serializers.@{service.scalaCompatConstants.WildcardImport} @for(method <- service.methods) { val @{method.name}Descriptor: MethodDescriptor[@method.inputTypeUnboxed, @method.outputTypeUnboxed] = diff --git a/codegen/src/main/twirl/templates/ScalaServer/Handler.scala.txt b/codegen/src/main/twirl/templates/ScalaServer/Handler.scala.txt index a5ce73938..697f87410 100644 --- a/codegen/src/main/twirl/templates/ScalaServer/Handler.scala.txt +++ b/codegen/src/main/twirl/templates/ScalaServer/Handler.scala.txt @@ -121,7 +121,7 @@ object @{serviceName}Handler { implicit val ec: ExecutionContext = mat.executionContext val spi = TelemetryExtension(system).spi - import @{service.name}.Serializers._ + import @{service.name}.Serializers.@{service.scalaCompatConstants.WildcardImport} def handle(request: model.HttpRequest, method: String): scala.concurrent.Future[model.HttpResponse] = GrpcMarshalling.negotiated(request, (reader, writer) => diff --git a/gradle-plugin/src/main/groovy/org/apache/pekko/grpc/gradle/PekkoGrpcPluginExtension.groovy b/gradle-plugin/src/main/groovy/org/apache/pekko/grpc/gradle/PekkoGrpcPluginExtension.groovy index fcfd8f79b..28df45d6c 100644 --- a/gradle-plugin/src/main/groovy/org/apache/pekko/grpc/gradle/PekkoGrpcPluginExtension.groovy +++ b/gradle-plugin/src/main/groovy/org/apache/pekko/grpc/gradle/PekkoGrpcPluginExtension.groovy @@ -14,11 +14,11 @@ import org.gradle.api.Project class PekkoGrpcPluginExtension { - static final String PROTOC_VERSION = "3.20.1" // checked synced by VersionSyncCheckPlugin + static final String PROTOC_VERSION = "3.24.0" // checked synced by VersionSyncCheckPlugin static final String PROTOC_PLUGIN_SCALA_VERSION = "2.12" - static final String GRPC_VERSION = "1.54.2" // checked synced by VersionSyncCheckPlugin + static final String GRPC_VERSION = "1.61.1" // checked synced by VersionSyncCheckPlugin static final String PLUGIN_CODE = 'org.apache.pekko.grpc.gradle' diff --git a/interop-tests/src/test/scala/org/apache/pekko/grpc/scaladsl/NonBalancingIntegrationSpec.scala b/interop-tests/src/test/scala/org/apache/pekko/grpc/scaladsl/NonBalancingIntegrationSpec.scala index 6eedbee5d..1c3079f8f 100644 --- a/interop-tests/src/test/scala/org/apache/pekko/grpc/scaladsl/NonBalancingIntegrationSpec.scala +++ b/interop-tests/src/test/scala/org/apache/pekko/grpc/scaladsl/NonBalancingIntegrationSpec.scala @@ -17,7 +17,6 @@ import java.net.InetSocketAddress import org.apache.pekko import pekko.actor.ActorSystem import pekko.grpc.GrpcClientSettings -import pekko.grpc.internal.ClientConnectionException import pekko.grpc.scaladsl.tools.MutableServiceDiscovery import pekko.http.scaladsl.Http import pekko.stream.{ Materializer, SystemMaterializer } @@ -184,8 +183,7 @@ class NonBalancingIntegrationSpec(backend: String) val failure = client.sayHello(HelloRequest(s"Hello friend")).failed.futureValue.asInstanceOf[StatusRuntimeException] - failure.getStatus.getCode should be(Code.UNAVAILABLE) - client.closed.failed.futureValue shouldBe a[ClientConnectionException] + failure.getStatus.getCode should (equal(Code.UNKNOWN).or(equal(Code.UNAVAILABLE))) } "not fail when no valid endpoints are provided but no limit on attempts is set" in { diff --git a/maven-plugin/src/main/maven/plugin.xml b/maven-plugin/src/main/maven/plugin.xml index 00f9767fc..6c01eec63 100644 --- a/maven-plugin/src/main/maven/plugin.xml +++ b/maven-plugin/src/main/maven/plugin.xml @@ -95,7 +95,7 @@ ${pekko-grpc.protoPaths} ${pekko-grpc.outputDirectory} - ${pekko-grpc.protoc-version} + ${pekko-grpc.protoc-version} @@ -187,7 +187,7 @@ ${pekko-grpc.protoPaths} ${pekko-grpc.outputDirectory} - ${pekko-grpc.protoc-version} + ${pekko-grpc.protoc-version} diff --git a/plugin-tester-java/pom.xml b/plugin-tester-java/pom.xml index b0c96b038..bf4fc85d1 100644 --- a/plugin-tester-java/pom.xml +++ b/plugin-tester-java/pom.xml @@ -25,7 +25,7 @@ 3.1.2 3.0.0 1.0.0 - 1.54.2 + 1.61.1 UTF-8 diff --git a/plugin-tester-scala/pom.xml b/plugin-tester-scala/pom.xml index d86e23def..c702c2233 100644 --- a/plugin-tester-scala/pom.xml +++ b/plugin-tester-scala/pom.xml @@ -24,7 +24,7 @@ 1.8 1.0.2 1.0.0 - 1.54.2 + 1.61.1 UTF-8 diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 9aed4e341..cb992539f 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -32,12 +32,12 @@ object Dependencies { val pekkoHttp = PekkoHttpDependency.version val pekkoHttpBinary = pekkoHttp.take(3) - val grpc = "1.54.2" // checked synced by VersionSyncCheckPlugin + val grpc = "1.61.1" // checked synced by VersionSyncCheckPlugin // Even referenced explicitly in the sbt-plugin's sbt-tests // If changing this, remember to update protoc plugin version to align in // maven-plugin/src/main/maven/plugin.xml and org.apache.pekko.grpc.sbt.PekkoGrpcPlugin - val googleProtoc = "3.20.1" // checked synced by VersionSyncCheckPlugin - val googleProtobufJava = "3.21.12" + val googleProtoc = "3.24.0" // checked synced by VersionSyncCheckPlugin + val googleProtobufJava = "3.24.0" val scalaTest = "3.2.18" diff --git a/project/plugins.sbt b/project/plugins.sbt index 97de791af..89066d604 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -51,4 +51,4 @@ libraryDependencies += "org.eclipse.jgit" % "org.eclipse.jgit" % "5.13.1.2022061 // scripted testing libraryDependencies += "org.scala-sbt" %% "scripted-plugin" % sbtVersion.value -libraryDependencies += "com.thesamet.scalapb" %% "compilerplugin" % "0.11.13" +libraryDependencies += "com.thesamet.scalapb" %% "compilerplugin" % "0.11.14" diff --git a/runtime/src/main/mima-filters/1.1.x.backwards.excludes/io.grpc-upgrade.backwards.excludes b/runtime/src/main/mima-filters/1.1.x.backwards.excludes/io.grpc-upgrade.backwards.excludes new file mode 100644 index 000000000..218a9f550 --- /dev/null +++ b/runtime/src/main/mima-filters/1.1.x.backwards.excludes/io.grpc-upgrade.backwards.excludes @@ -0,0 +1,19 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# Upgrade to io.grpc 1.60 caused this bin compat issue +ProblemFilters.exclude[DirectMissingMethodProblem]("org.apache.pekko.grpc.internal.PekkoDiscoveryNameResolverProvider.this") diff --git a/runtime/src/main/scala/org/apache/pekko/grpc/internal/NettyClientUtils.scala b/runtime/src/main/scala/org/apache/pekko/grpc/internal/NettyClientUtils.scala index 07b1d8a3a..8a9c3f242 100644 --- a/runtime/src/main/scala/org/apache/pekko/grpc/internal/NettyClientUtils.scala +++ b/runtime/src/main/scala/org/apache/pekko/grpc/internal/NettyClientUtils.scala @@ -58,6 +58,7 @@ object NettyClientUtils { new PekkoDiscoveryNameResolverProvider( settings.serviceDiscovery, settings.defaultPort, + settings.serviceName, settings.servicePortName, settings.serviceProtocol, settings.resolveTimeout)) diff --git a/runtime/src/main/scala/org/apache/pekko/grpc/internal/PekkoDiscoveryNameResolverProvider.scala b/runtime/src/main/scala/org/apache/pekko/grpc/internal/PekkoDiscoveryNameResolverProvider.scala index 66b5735ad..2982ce8d2 100644 --- a/runtime/src/main/scala/org/apache/pekko/grpc/internal/PekkoDiscoveryNameResolverProvider.scala +++ b/runtime/src/main/scala/org/apache/pekko/grpc/internal/PekkoDiscoveryNameResolverProvider.scala @@ -24,6 +24,7 @@ import scala.concurrent.duration.FiniteDuration class PekkoDiscoveryNameResolverProvider( discovery: ServiceDiscovery, defaultPort: Int, + serviceName: String, portName: Option[String], protocol: Option[String], resolveTimeout: FiniteDuration)(implicit ec: ExecutionContext) @@ -34,8 +35,7 @@ class PekkoDiscoveryNameResolverProvider( override def getDefaultScheme: String = "http" - override def newNameResolver(targetUri: URI, args: NameResolver.Args): PekkoDiscoveryNameResolver = { - require(targetUri.getAuthority != null, s"target uri should not have null authority, got [$targetUri]") - new PekkoDiscoveryNameResolver(discovery, defaultPort, targetUri.getAuthority, portName, protocol, resolveTimeout) - } + override def newNameResolver(targetUri: URI, args: NameResolver.Args): PekkoDiscoveryNameResolver = + new PekkoDiscoveryNameResolver(discovery, defaultPort, serviceName, portName, protocol, resolveTimeout) + } diff --git a/runtime/src/test/scala/org/apache/pekko/grpc/internal/PekkoDiscoveryNameResolverProviderSpec.scala b/runtime/src/test/scala/org/apache/pekko/grpc/internal/PekkoDiscoveryNameResolverProviderSpec.scala index ba19adbd0..aef2c3461 100644 --- a/runtime/src/test/scala/org/apache/pekko/grpc/internal/PekkoDiscoveryNameResolverProviderSpec.scala +++ b/runtime/src/test/scala/org/apache/pekko/grpc/internal/PekkoDiscoveryNameResolverProviderSpec.scala @@ -61,6 +61,7 @@ class PekkoDiscoveryNameResolverProviderSpec val provider = new PekkoDiscoveryNameResolverProvider( discovery, 443, + serviceName, portName = None, protocol = None, resolveTimeout = 3.seconds) diff --git a/sbt-plugin/src/sbt-test/gen-scala-server/00-interop/build.sbt b/sbt-plugin/src/sbt-test/gen-scala-server/00-interop/build.sbt index cdbdb496e..b06b0c151 100644 --- a/sbt-plugin/src/sbt-test/gen-scala-server/00-interop/build.sbt +++ b/sbt-plugin/src/sbt-test/gen-scala-server/00-interop/build.sbt @@ -13,7 +13,7 @@ scalaVersion := "2.12.18" organization := "org.apache.pekko" -val grpcVersion = "1.54.2" // checked synced by VersionSyncCheckPlugin +val grpcVersion = "1.61.1" // checked synced by VersionSyncCheckPlugin libraryDependencies ++= Seq( "io.grpc" % "grpc-interop-testing" % grpcVersion % "protobuf-src", diff --git a/sbt-plugin/src/sbt-test/gen-scala-server/06-compatibility-plugins/build.sbt b/sbt-plugin/src/sbt-test/gen-scala-server/06-compatibility-plugins/build.sbt index 5e774789b..ec0271f37 100644 --- a/sbt-plugin/src/sbt-test/gen-scala-server/06-compatibility-plugins/build.sbt +++ b/sbt-plugin/src/sbt-test/gen-scala-server/06-compatibility-plugins/build.sbt @@ -11,6 +11,6 @@ // https://github.com/akka/akka-grpc/pull/1279 scalaVersion := "2.12.18" -enablePlugins(ProtocJSPlugin) // enable it first to test possibility of getting overriden +enablePlugins(ProtocGoPlugin) // enable it first to test possibility of getting overriden enablePlugins(PekkoGrpcPlugin) diff --git a/sbt-plugin/src/sbt-test/gen-scala-server/06-compatibility-plugins/project/ProtocJSPlugin.scala b/sbt-plugin/src/sbt-test/gen-scala-server/06-compatibility-plugins/project/ProtocGoPlugin.scala similarity index 76% rename from sbt-plugin/src/sbt-test/gen-scala-server/06-compatibility-plugins/project/ProtocJSPlugin.scala rename to sbt-plugin/src/sbt-test/gen-scala-server/06-compatibility-plugins/project/ProtocGoPlugin.scala index e050644dc..0875b6f20 100644 --- a/sbt-plugin/src/sbt-test/gen-scala-server/06-compatibility-plugins/project/ProtocJSPlugin.scala +++ b/sbt-plugin/src/sbt-test/gen-scala-server/06-compatibility-plugins/project/ProtocGoPlugin.scala @@ -12,12 +12,14 @@ import sbt._ import sbtprotoc.ProtocPlugin import sbtprotoc.ProtocPlugin.autoImport.PB -object ProtocJSPlugin extends AutoPlugin { +object ProtocGoPlugin extends AutoPlugin { override def trigger: PluginTrigger = noTrigger override def requires: Plugins = ProtocPlugin override def projectSettings: Seq[Def.Setting[_]] = - Seq(Compile, Test).flatMap(inConfig(_)(PB.targets += PB.gens.js -> resourceManaged.value / "js")) + Seq(Compile, Test).flatMap(inConfig(_)( + Seq( + PB.targets += PB.gens.go -> resourceManaged.value / "go"))) } diff --git a/sbt-plugin/src/sbt-test/gen-scala-server/06-compatibility-plugins/src/main/protobuf/helloworld.proto b/sbt-plugin/src/sbt-test/gen-scala-server/06-compatibility-plugins/src/main/protobuf/helloworld.proto index 0f4426692..0d2d6f551 100644 --- a/sbt-plugin/src/sbt-test/gen-scala-server/06-compatibility-plugins/src/main/protobuf/helloworld.proto +++ b/sbt-plugin/src/sbt-test/gen-scala-server/06-compatibility-plugins/src/main/protobuf/helloworld.proto @@ -1,5 +1,6 @@ syntax = "proto3"; +option go_package = "github.com/apache/pekko-grpc"; option java_multiple_files = true; option java_package = "example.myapp.helloworld.grpc"; option java_outer_classname = "HelloWorldProto"; diff --git a/sbt-plugin/src/sbt-test/gen-scala-server/06-compatibility-plugins/src/test/protobuf/echo.proto b/sbt-plugin/src/sbt-test/gen-scala-server/06-compatibility-plugins/src/test/protobuf/echo.proto index de1aed8ea..819bd2fb6 100644 --- a/sbt-plugin/src/sbt-test/gen-scala-server/06-compatibility-plugins/src/test/protobuf/echo.proto +++ b/sbt-plugin/src/sbt-test/gen-scala-server/06-compatibility-plugins/src/test/protobuf/echo.proto @@ -1,5 +1,6 @@ syntax = "proto3"; +option go_package = "github.com/apache/pekko-grpc"; option java_multiple_files = true; option java_package = "example.myapp.echo.grpc"; diff --git a/sbt-plugin/src/sbt-test/gen-scala-server/06-compatibility-plugins/test b/sbt-plugin/src/sbt-test/gen-scala-server/06-compatibility-plugins/test index 50cbc18bb..2c38813bd 100644 --- a/sbt-plugin/src/sbt-test/gen-scala-server/06-compatibility-plugins/test +++ b/sbt-plugin/src/sbt-test/gen-scala-server/06-compatibility-plugins/test @@ -1,8 +1,8 @@ > compile -$ exists target/scala-2.12/resource_managed/main/js/hellorequest.js +$ exists target/scala-2.12/resource_managed/main/go/github.com/apache/pekko-grpc/helloworld.pb.go $ exists target/scala-2.12/pekko-grpc/main/example/myapp/helloworld/grpc/HelloRequest.scala > test:compile -$ exists target/scala-2.12/resource_managed/test/js/echomessage.js +$ exists target/scala-2.12/resource_managed/test/go/github.com/apache/pekko-grpc/echo.pb.go $ exists target/scala-2.12/pekko-grpc/test/example/myapp/echo/grpc/EchoMessage.scala diff --git a/scripts/link-validator.conf b/scripts/link-validator.conf index 728b24e47..122fcd572 100644 --- a/scripts/link-validator.conf +++ b/scripts/link-validator.conf @@ -34,6 +34,7 @@ site-link-validator { non-https-whitelist = [ # license report + "http://www.jetbrains.org", "http://aopalliance.sourceforge.net", "http://asm.ow2.io/", "http://checkerframework.org",