com.bedatadriven.jackson.datatype.jts.JtsModule not working with springboot 2.2.4 - spring-boot

I am trying to serialize/deserialize org.locationtech.jts.geom.Geometry(version 1.16.0) using com.bedatadriven.jackson.datatype.jts.JtsModule. It comes packaged with:
<dependency>
<groupId>com.graphhopper.external</groupId>
<artifactId>jackson-datatype-jts</artifactId>
<version>1.0-2.7</version>
</dependency>
I have registered it using spring configuration mechanism:
#Bean
public JtsModule jtsModule()
{
return new JtsModule();
}
But somehow com.bedatadriven.jackson.datatype.jts.serialization.GeometryDeserializer is not invoked.
Is there something else needed to be done?

GeometryDeserializer / GeometrySerializer worked for com.vividsolutions.jts.geom.Geometry
An issue is open about it here
You can create your custom serializer and deserializer for org.locationtech.jts.geom.Geometry using same code available.
Example for point
There is a PR for Upgrade to Locationtech jts but not merged yet

Related

springdoc openapi nested endpoints not being picked up

I'm using springdoc-openapi 1.6.11 and I'm finding that nested endpoints in my Controllers are not being picked up in the Swagger docs.
For example, the controller is annotated with#RequestMapping("/a/patient").
Then I'll have a method inside the controller such as: #PutMapping("profile/height")
But the generated Swagger isn't picking it up.
My Config class looks like this:
#Configuration
public class OpenApiConfig {
#Bean
public OpenAPI springOpenAPI() {
return new OpenAPI()
.info(new Info().title("BubbleCare API")
.description("BubbleCare service documentation.")
.version(getClass().getPackage().getImplementationVersion())
.license(new License().name("Terms of Use")
.url("https://myapi.com/terms.html")));
}
and my properties look like this:
springdoc.cache.disabled= true
springdoc.pathsToMatch=/a/**,/d/**
springdoc.swagger-ui.operationsSorter=alpha
I don't know why, I'll be coding for a while, and everything seems okay, but then the Swagger generation just happens to freeze and not want to update any new endpoints that I write.
Any ideas?
Everything looks fine to me. There might be a chance that your dependencies got mucked up, you can try purging the local maven repository using below command:
mvn dependency:purge-local-repository
Then you can clean and install again for your project:
mvn dependency:purge-local-repository clean install
You can learn more about this command here: https://maven.apache.org/plugins/maven-dependency-plugin/examples/purging-local-repository.html

com.oracle.truffle.polyglot.PolyglotImpl (in unnamed module) cannot access class org.graalvm.polyglot.impl.AbstractPolyglotImpl

I tried to extend scaffolded quarkus demo, https://code.quarkus.io/, with polyglot code for GraalVM:
#GET
#Produces(MediaType.TEXT_PLAIN)
public String hello() {
String out = "From JS:";
try (Context context = Context.create()) {
Value function = context.eval("js", "x => x+1");
assert function.canExecute();
int x = function.execute(41).asInt();
out=out+x;
System.out.println(out);
}
return "hello";
}
I added dependencies to pom.xml as suggested here [https://stackoverflow.com/questions/54384499/illegalstateexception-no-language-and-polyglot-implementation-was-found-on-the]
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js</artifactId>
<version>20.1.0</version>
</dependency>
<dependency>
<groupId>org.graalvm.js</groupId>
<artifactId>js-scriptengine</artifactId>
<version>20.1.0</version>
</dependency>
<dependency>
<groupId>org.graalvm.truffle</groupId>
<artifactId>truffle-api</artifactId>
<version>20.1.0</version>
</dependency>
But when I run on cmd line
./mvnw clean package
Test fails with exception, which I do not understand.
2020-06-22 19:26:56,328 ERROR [io.qua.ver.htt.run.QuarkusErrorHandler]
(executor-thread-1) HTTP Request to /hello failed, error id: 996b0479-d836-47a5-bbcb-67bd876f9277-1: org.jboss.resteasy.spi.UnhandledException:
java.lang.IllegalAccessError: superclass access check failed:
class com.oracle.truffle.polyglot.PolyglotImpl (in unnamed module #0x7bf61ba2) cannot access class org.graalvm.polyglot.impl.AbstractPolyglotImpl (in module org.graalvm.sdk)
because module org.graalvm.sdk does not export org.graalvm.polyglot.impl to unnamed module #0x7bf61ba2
UPDATE:
It looks like regression in quarkus, https://github.com/quarkusio/quarkus/issues/10226.
App test is passing when used with quarkus 1.2.1 (instead of 1.5.2).
Look into the mvn dependency:tree -- it turns out that org.graalvm.js:js:20.1.0 depends on org.graalvm.sdk:graal-sdk:19.3.1. I'd personally call that GraalVM JS bug.
If you add an explicit dependency on org.graalvm.sdk:graal-sdk:20.1.0, it should work.
(At least it did for me, but I was getting a different error than you, so not sure.)
EDIT: as I was warned about in the comment, it is not true that org.graalvm.js:js:20.1.0 depends on org.graalvm.sdk:graal-sdk:19.3.1. Instead, there must be something else that forces graal-sdk to 19.3.1, perhaps something from Quarkus. Explicitly managing it to 20.1.0 should still help.
are you maybe executing that on GraalVM 19.3.1? That is known to confuse the system. Our strong suggestion is to EITHER run on a GraalVM (which automatically includes a proper version of Graal.js, no further input needed), OR run on a Stock JDK and import the respective JARs from Maven. If you import (a different version of) our Jars from maven on a GraalVM, then you might run into conflicts like that.

Springdoc: got 404 when open swagger-ui.html

I got latest Spring Boot app and springdoc.swagger-ui on board.
<dependency>
<groupId>io.swagger</groupId>
<artifactId>swagger-annotations</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-ui</artifactId>
<version>1.2.32</version>
</dependency>
My application.properties contains springdoc.swagger-ui.path=/swagger-ui-openapi.html
When I run application via Intellij IDEA http://localhost:8080/swagger-ui-openapi.html brings me to http://localhost:8080/swagger-ui/index.html?configUrl=/v3/api-docs/swagger-config
and Swagger UI page loads successfully.
But if I start the app via command line: "java -jar my-app.jar", I got 404 in browser and Error in logs 'Circular view path [error]' when trying to reach http://localhost:8080/swagger-ui-openapi.html
and it redirrects me to http://localhost:8080/swagger-ui/index.html?configUrl=/v3/api-docs/swagger-config
javax.servlet.ServletException: Circular view path [error]: would dispatch back to the current handler URL [/error] again. Check your ViewResolver setup! (Hint: This may be the result of an unspecified view, due to default view name generation.)
However http://localhost:8080/v3/api-docs is reachable and schema is available at this address.
How can I fix this?
What worked in my case when your application is running behind a proxy, a load-balancer or in the cloud.
In your Spring Boot application make sure your application handles this header: X-Forwarded-For.
There are two ways to achieve this:
In your properties file add:
server.use-forward-headers=true
If this is not enough, Spring Framework provides a ForwardedHeaderFilter. You can register it as a Servlet Filter in your application by setting server.forward-headers-strategy is set to FRAMEWORK.
Since Spring Boot 2.2, this is the new property to handle reverse proxy headers:
In your properties file add
server.forward-headers-strategy=framework
And you can add the following bean to your application:
#Bean
ForwardedHeaderFilter forwardedHeaderFilter() {
return new ForwardedHeaderFilter();
}
If you already have static content on your root, and you don’t want it to be overridden by springdoc-openapi-ui configuration, you can just define a custom configuration of the swagger-ui, in order not to override the configuration of your files from in your context-root:
For example use in your properties file:
springdoc.swagger-ui.path= /swagger-ui/api-docs.html
ref:
https://springdoc.org/
For this problem, my conclusion is:
(1) Starting it in IDEA is fine
(2) Repackaging the jar with spring-boot-maven-plugin and starting it with 'java -jar' is fine as well.
(3) if I tried to starting with such as 'java -classpath ".:.conf" DemoApplication', it does not work.
So, for packaging, i use the spring-boot-maven-plugin.
You don't need swagger-annotations v1.6.1 dependency for springdoc-openapi;
By default, with springdoc you need no additonal settings of any ViewResolver.
You can have a look at some sample code:
https://github.com/springdoc/springdoc-openapi-demos

ignite-indexing and H2 version

When I use the spatial index module in ignite1.6.0 , I found it depends 1.3.175 version of the H2, but I need to use the 1.4.X h2 version.
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.3.175</version>
<scope>compile</scope>
</dependency>
This method org.apache.ignite.internal.processors.query.h2.IgniteH2Indexing # start will call org.h2.constant.SysProperties and org.h2.util.Utils, in front of the class in the 1.3.176 version of the above have been It does not exist, the latter class is missing serializer variables.
if (SysProperties.serializeJavaObject) {
U.warn(log, "Serialization of Java objects in H2 was enabled.");
SysProperties.serializeJavaObject = false;
}
if (Utils.serializer != null)
U.warn(log, "Custom H2 serialization is already configured, will override.");
Utils.serializer = h2Serializer();
Is there any way to solve it?
Ignite depends on H2 1.3.175 and you can't use any other version. If you already have some code that depends on 1.4, you should isolate Ignite-related code in a separate module in your project. This way different versions of H2 will coextist.

New Relic for Spring Boot

Recently, we convert a tomcat/spring app to spring boot. Everything is working fine apart from new relic. Is there a way I can easily config new relic with spring boot project. I don't want to hard code the location of new relic agent jar path, then run the spring boot project with the path.
edit: Spring boot project is with maven
You can include NewRelic Maven dependency and use maven-dependency-plugin to unpack in into your target/classes directory, which allows Maven to include it into final Jar file. Then you have to add Premain-Class attribute into manifest file and you can use your application jar as -javaagent source. You can find details on my blog post
Step by step instructions
Extract the files from the newrelic java agent archive.
Create a directory named newrelic in the root of your application.
Place the newrelic.jar from the archive in the above created newrelic folder
Place the newrelic.yml YAML config file in the above created newrelic folder.
Update the values in newrelic.yml as below.
license_key: 'your license key'
app_name: ‘Your application name’
Run you application by using the option javaagent
java -javaagent:newrelic\newrelic.jar -jar yourapplication.jar
-javaagent option needs to be before the -jar so the agent can start
I was stuck with the same issue, here is what I figured out. I implemented the 2nd way for my applications.
There are 3 ways to integrate New Relic with a Spring Boot Application-
Using the Java Agent provided by New Relic
Using New Relic's Micrometer Dependency
Micormeter's New Relic Dependency
1. Configuration using Java Agent Provided By New Relic
Download the Java Agent from this URL- https://docs.newrelic.com/docs/release-notes/agent-release-notes/java-release-notes/
Extract it.
Modify the newrelic.yml file inside the extracted folder to include your
license_key:
app_name:
Create a SpringBoot application with some REST endpoints.
Build the application.
Navigate to the root path where you have extracted the newrelic java agent.
Enter this command
java -javagent:<path to your new relic jar>\newrelic.jar -jar <path to your application jar>\<you rapplication jar name>.jar
To view the application metrics-
Log in to your New Relic account.
Go to Explorer Tab.
Click on Services-APM
You can see the name of your application(which you had mentioned in the newrelic.yml file) listed there.
Click on the application name.
The dashboard should look something like this.
Using New Relic's Micrometer Dependency is the preferred way to do it.
2. Configuration using New Relic's Micrometer Dependency
Add this dependency
<dependency>
<groupId>com.newrelic.telemetry</groupId>
<artifactId>micrometer-registry-new-relic</artifactId>
<version>0.7.0</version>
</dependency>
Modify the MicrometerConfig.java class to add your API Key and Application name.
import java.net.InetAddress;
import java.net.UnknownHostException;
import org.springframework.boot.actuate.autoconfigure.metrics.CompositeMeterRegistryAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.MetricsAutoConfiguration;
import org.springframework.boot.actuate.autoconfigure.metrics.export.simple.SimpleMetricsExportAutoConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.newrelic.telemetry.Attributes;
import com.newrelic.telemetry.micrometer.NewRelicRegistry;
import com.newrelic.telemetry.micrometer.NewRelicRegistryConfig;
import java.time.Duration;
import io.micrometer.core.instrument.config.MeterFilter;
import io.micrometer.core.instrument.util.NamedThreadFactory;
#Configuration
#AutoConfigureBefore({ CompositeMeterRegistryAutoConfiguration.class, SimpleMetricsExportAutoConfiguration.class })
#AutoConfigureAfter(MetricsAutoConfiguration.class)
#ConditionalOnClass(NewRelicRegistry.class)
public class MicrometerConfig {
#Bean
public NewRelicRegistryConfig newRelicConfig() {
return new NewRelicRegistryConfig() {
#Override
public String get(String key) {
return null;
}
#Override
public String apiKey() {
return "your_api_key"; // for production purposes take it from config file
}
#Override
public Duration step() {
return Duration.ofSeconds(5);
}
#Override
public String serviceName() {
return "your_service_name"; // take it from config file
}
};
}
#Bean
public NewRelicRegistry newRelicMeterRegistry(NewRelicRegistryConfig config) throws UnknownHostException {
NewRelicRegistry newRelicRegistry = NewRelicRegistry.builder(config)
.commonAttributes(new Attributes().put("host", InetAddress.getLocalHost().getHostName())).build();
newRelicRegistry.config().meterFilter(MeterFilter.ignoreTags("plz_ignore_me"));
newRelicRegistry.config().meterFilter(MeterFilter.denyNameStartsWith("jvm.threads"));
newRelicRegistry.start(new NamedThreadFactory("newrelic.micrometer.registry"));
return newRelicRegistry;
}
}
Run the application.
To view the Application metrics-
Log in to your New Relic account.
Go to Explorer Tab.
Click on Services-OpenTelemetry
You can see the name of your application(which you had mentioned in the MicrometerConfig file) listed there.
Click on the application name.
The dashboard should look something like this.
Here is the link to my original question.

Resources