Skip to content
Laird Nelson edited this page Apr 26, 2022 · 68 revisions

Frequently Asked Questions

Welcome to the Helidon FAQ! If you're reading this, you're a reader, so you might also be interested in our website.

What is this document?

This is a living (somewhat irreverent) document (and Wiki page!) cataloging frequently asked and frequently encountered questions around the Helidon project. It may be updated, edited, reorganized, repaginated, or otherwise generally munged at any time for any reason without prior notice. There may be parts of this document that are incomplete, "to be done", missing, and so on. No guarantees are made about link longevity or content lifespan. We like to keep this document fresh.

How should I read it?

You may read it straight through if you wish, though it has been designed to be deeply linkable. As questions come up, we post deep links to the relevant section in this document in response.

Additionally, since Helidon is (among many other things) a careful mix of our own code and repackaged code, some questions that seem like they concern Helidon are actually questions about its constituent technologies. This document tries to balance giving you a useful answer to a question, while not also, say, rewriting the documentation for Jakarta RESTful Web Services, or CDI, or Netty, or one of the other technologies that help make Helidon work. So some topics you may find here are really better addressed by other documentation sites, and we've tried to link to them as appropriate.

Does it contain all the things I need to know about Helidon?

No, not at all. For that, you want our documentation site.

If this document says X and the website says Y, which is right?

The website.

Are there code samples?

Yes. See below. However, if you're looking for code to copy and paste, you're better served by looking at our examples. (Also: copying and pasting code without understanding what it does is almost always the wrong thing to do. You may notice that most of the examples in this FAQ contain comments designed to make copying and pasting without editing as clumsy and awkward as possible. That's on purpose.)

What is Helidon?

Helidon is a set of Java libraries for writing microservices, oriented around a Netty-based webserver. Helidon comes in two flavors: Helidon SE (reactive and no magic) and Helidon MP (a MicroProfile implementation). It's open source and available under the Apache 2.0 license.

What's the difference between Helidon SE and Helidon MP?

The difference is primarily programming style.

Helidon MP is our implementation of the Eclipse MicroProfile specification. MicroProfile has familiar enterprise Java APIs like Jakarta RESTful Web Services, CDI and JSON-P. MicroProfile also specifies other microservice-focused APIs like MicroProfile Health and MicroProfile Metrics. MicroProfile APIs tend to follow a declarative style with lots of annotations. If you are used to programming in a Jakarta EE- or Spring Boot-like style, then Helidon MP will feel familiar.

Helidon SE is based on our own reactive APIs. It uses a functional style of programming with almost no annotations. You're just calling methods on plain old Java objects (POJOs). No magic!

How do I get started?

See the Getting Started section in our documentation!

What versions of Java, Maven and all the other stuff do I need?

Helidon's prerequisites are available on our documentation site. (They're not written here because then they'd need to be maintained in two places.)

Helidon MP Topics

True MicroProfile Topics (not other topics in disguise)

What version of MicroProfile does Helidon MP support?

Please see the Supported APIs page in our Wiki.

What's the difference between helidon-microprofile and helidon-microprofile-core dependency bundles?

  • io.helidon.microprofile.bundles:helidon-microprofile bundles contains support for all of the foundational MicroProfile features. It's handy for getting going quickly and experimenting. It probably includes too much for any given single use case, but it is definitely convenient.
  • io.helidon.microprofile.bundles:helidon-microprofile-core bundle contains support for minimal MicroProfile features. You then add additional dependencies as you need them. Using this core bundle is recommended for production services because it minimizes dependencies and footprint.

Here is an example that uses the core bundle: MicroProfile Multi-Port Example. You can also view the contents of the full bundle to see what you might need to add to the core bundle.

When I run my Helidon MP application it complains about providers missing for authentication, tracing, etc. What's going on?

You are likely using the full helidon-microprofile dependency bundle (see the previous question). That bundle includes Helidon MicroProfile support for most of the MicroProfile features, but not necessarily providers. For example, with tracing you need to add a tracing provider.

On the other hand, if you do not want those features in your application, then you should start with the core dependency bundle and add only what you need. See the previous question.

Jakarta RESTful Web Services-, Servlet- and Web-Related Topics

What version of Servlet does Helidon MP support?

Helidon MP is not a Servlet implementation, nor does it supply one, so the answer is none. This is deliberate.

How do I get an HttpServletRequest then?

You can't.

But I need headers, or something else that the HttpServletRequest class makes available!

The short answer is: almost certainly Jakarta RESTful Web Services has an analogous object that will do what you want instead.

Helidon MP is a MicroProfile implementation, which means by definition that it is also a Jakarta RESTful Web Services implementation (formerly JAX-RS)—it packages Jersey. By the time you're talking about requests and responses, you are "in" Jersey, and so you do things the Jersey way; Helidon MP is waiting for your response so it can route it back "through" the webserver and over the wire back to the user. But "inside" Jakarta RESTful Web Services constructs—resource classes, filters—loosely speaking there's very little Helidon MP to see. And no Servlet.

So then: most, if not all, of the things you can do with an HttpServletRequest you can do with equivalent Jakarta RESTful Web Services constructs. For example, you can @Inject an instance of HttpHeaders to get the HTTP headers you need.

Similar useful classes include:

These are arbitrary examples and there are others; a full Jakarta RESTful Web Services tutorial is beyond the scope of this document. You may wish to consult the specification.

How do I do {web-related thing} using Helidon MP?

Most of the time, this is not a Helidon MP question.

This category of question reduces to: "How do I do {web thing} in Jakarta RESTful Web Services/Jersey?"

How do I use Jackson in Helidon MP?

(Strictly speaking, this is not a Helidon MP question.)

This question is really: "How do I use Jackson in Jersey?"

How do I use Jackson in Jersey?

As you might expect, the Jersey documentation has the answer.

If you are using Helidon's MicroProfile "bundles" dependency, you'll probably need to exclude some stuff too:

<dependency>
    <groupId>io.helidon.microprofile.bundles</groupId>
    <artifactId>helidon-microprofile</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-json-binding</artifactId>
        </exclusion>
        <exclusion>
            <groupId>jakarta.json.bind</groupId>
            <artifactId>jakarta.json.bind-api</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.eclipse</groupId>
            <artifactId>yasson</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.glassfish.jersey.media</groupId>
    <artifactId>jersey-media-json-jackson</artifactId>
</dependency>
Aha! I gotcha! That was Helidon MP-specific!

Yes and no. You'll note that if you had to do all that, it's because you chose to import one of our opinionated bundles, rather than selecting your dependencies individually according to your preferences.

CDI-Related Topics

How do I make a class a CDI bean?

(Strictly speaking, this is not a Helidon MP question. This is a CDI question.)

You'll need to do a few things.

  1. First, verify that you have a src/main/resources/META-INF/beans.xml file (or src/test/resources/META-INF/beans.xml, or both). A META-INF/beans.xml classpath resource marks that classpath root (usually a jar file) as a bean archive. CDI over the years and versions has changed the micro-level details of exactly what this file means and what its presence and absence mean, but it's best to have one. Now every Java class that ends up under this classpath root (which usually ends up being target/classes or target/test-classes in a Maven project after compilation) will be potentially discoverable in one way or another as a CDI bean.

  2. Second, make sure that beans.xml file looks like the following. If you're new to CDI and don't understand what you're doing, then make sure it looks exactly like the following:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="https://jakarta.ee/xml/ns/jakartaee"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee
                               https://jakarta.ee/xml/ns/jakartaee/beans_3_0.xsd"
           version="3.0"
           bean-discovery-mode="annotated">
      <!--
           This file was copied verbatim from the Helidon MP FAQ.
           You should probably look at it carefully to make sure it
           meets your needs and then remove this comment.
      -->
    </beans>

    Note in particular the bean-discovery-mode of annotated. You can read more about bean discovery modes in the CDI specification. If you are new to CDI, please leave this as annotated.

  3. Because you've now told CDI that it should discover only annotated beans, you need to place a bean-defining annotation on your class (that is under the classpath root that features META-INF/beans.xml, so usually src/main/java/your/package/here/YourClass.class). There are several bean-defining annotations but the easiest thing to do is assign your bean a scope. (If you don't know what a scope is, then this FAQ has to stop somewhere, so go read about scopes and CDI in general.)

Congratulations; you've made a CDI bean.

Can you give me an example?

Assuming src/main/resources/META-INF/beans.xml is in place with a bean-discovery-mode of annotated, here is an example class that is in the @Dependent scope that is, by virtue of being annotated with @Dependent—a bean-defining annotation—a CDI bean:

@Dependent
public class ThisClassIsAnExampleFromTheHelidonMPFAQ {
  public ThisClassIsAnExampleFromTheHelidonMPFAQ() {
    super();
  }
}

How do I run some code when Helidon MP starts?

Helidon MP is fundamentally a CDI container. So the question is really, "How do I run some code when a CDI container starts?"

How do I run some code when a CDI container starts?

(Strictly speaking, this is not a Helidon MP question.)

You write a particular kind of observer method in an enabled CDI managed bean somewhere that observes the initialization of the application scope.

The method can be named anything you like, can be public, package-protected, protected or private, returns void, and must take at least one parameter that is annotated with @Observes @Initialized(ApplicationScoped.class). (Usually this parameter is simply an Object that you can simply ignore since the specification does not mandate what it must be.) Any other parameter is treated as an injection point, so you can also receive dependencies this way for your method to work with.

Can you give me an example?

Here is an application scope initialization observer method. Remember, it must be declared in a class that is an enabled CDI managed bean:

private void thisIsAnExampleMethodFromTheHelidonMPFAQ(@Observes @Initialized(ApplicationScoped.class) final Object ignoredEvent) {
  // code you put here will be invoked when the CDI container starts, more specifically
  // when CDI's application scope is initialized
}

DataSource- and Connection Pool-Related Topics

What connection pools does Helidon MP support?

Helidon MP has support for two different connection pools:

  1. Oracle's Universal Connection Pool
  2. HikariCP

You choose one of them, never both.

What Maven dependencies do I need to use a connection pool?

Universal Connection Pool Maven dependencies

To use the Universal Connection Pool, ensure the following dependency is in your project's pom.xml's <dependencies> stanza:

<dependency>
  <groupId>io.helidon.integrations.cdi</groupId>
  <artifactId>helidon-integrations-cdi-datasource-ucp</artifactId>
  <!-- 
       It's actually best to manage this with Maven's <dependencyManagement> feature.
       If you opt for the explicit version here, always check
       https://search.maven.org/classic/#search%7Cga%7C1%7Chelidon for up-to-date
       available versions.
  -->
  <!-- <version>2.4.0</version> -->
  <scope>runtime</scope>
</dependency>

HikariCP connection pool Maven dependencies

To use the HikariCP connection pool, ensure the following dependency is in your project's pom.xml's <dependencies> stanza:

<dependency>
  <groupId>io.helidon.integrations.cdi</groupId>
  <artifactId>helidon-integrations-cdi-datasource-hikaricp</artifactId>
  <!-- 
       It's actually best to manage this with Maven's <dependencyManagement> feature.
       If you opt for the explicit version here, always check
       https://search.maven.org/classic/#search%7Cga%7C1%7Chelidon for up-to-date
       available versions.
  -->
  <!-- <version>2.4.0</version> -->
  <scope>runtime</scope>
</dependency>

Once I've put my connection pool dependencies in Maven, what else do I need?

To use connection pool-managed DataSource instances in your code, you'll also need Maven dependencies corresponding to your database vendor's JDBC database driver. You can use any JDBC driver dependencies you like. Here are two arbitrary examples.

Oracle JDBC driver dependencies

The Oracle Database JDBC driver is available on Maven Central and comes in a variety of flavors for a variety of use cases, all of which are documented, with examples, in the Developers Guide For Oracle JDBC 21c on Maven Central.

Some of the documented use cases include the Universal Connection Pool. You want to avoid those use cases since the Universal Connection Pool integration provided by Helidon already includes it.

Can you give me an example?

Please read Developers Guide For Oracle JDBC 21c on Maven Central and understand it.

As it spells out in detail, to add just the Oracle Database 21c production JDBC driver to your project, put the following in your project's pom.xml's <dependencies> stanza, if it is not already there or inherited:

<dependencies>
  <dependency>
    <!--
         See
         https://www.oracle.com/database/technologies/maven-central-guide.html
         for more details.
     -->
    <groupId>com.oracle.database.jdbc</groupId>
    <!--
         Why ojdbc*11*? Why not ojdbc*something else*? Because:
         (a) Helidon targets Java 17
         (b) Java 17 "includes" JDBC 4.3, not JDBC 4.2
         (c) ojdbc11 "includes" JDBC 4.3
         (d) ojdbc8 only "includes" JDBC 4.2
         Please see
         https://www.oracle.com/database/technologies/maven-central-guide.html
         for more details.
    -->
    <artifactId>ojdbc11</artifactId>
    <!-- 
       It's actually best to manage this with Maven's <dependencyManagement> feature.
       If you opt for the explicit version here, always check
       https://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22com.oracle.database.jdbc%22
       for up-to-date available versions, and see
       https://www.oracle.com/database/technologies/maven-central-guide.html
       for extremely important information.
    -->
    <!-- <version>21.3.0.0</version> -->
    <scope>runtime</scope>
  </dependency>
</dependencies>

This is only one of several possible use cases you may have and so is not universally suitable.

H2 JDBC driver dependencies

The H2 database is a simple database often used for unit testing.

Can you give me an example?

To add the H2 JDBC driver to your project, put the following in your project's pom.xml's <dependencies> stanza, if it is not already there or inherited:

<dependency>
  <groupId>com.h2database</groupId>
  <artifactId>h2</artifactId>
  <!-- 
       It's actually best to manage this with Maven's <dependencyManagement> feature.
       If you opt for the explicit version here, always check
       https://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22com.h2database%22%20AND%20a%3A%22h2%22
       for up-to-date available versions.
  -->
  <!-- <version>2.0.202</version> -->
  <scope>runtime</scope>
</dependency>

How can I configure a DataSource?

You configure a DataSource in Helidon MP like you configure everything else: using Helidon's built-in MicroProfile Config implementation.

The general pattern is to tell Helidon that you have a named javax.sql.DataSource instance you'd like to set up. Because Helidon MP uses MicroProfile Config as its configuration system, you can put this information in a variety of places.

Setting up a javax.sql.DataSource named yourDataSourceName isn't really different from the general process setting up other types of Java objects with names. For this reason, the general naming pattern Helidon integrations use is fully.qualified.java.class.name. followed by theNameYouChoose. followed by whateverTheActualPropertyIs. So for various javax.sql.DataSource configuration properties for a data source named yourDataSourceName, the properties would all start with javax.sql.DataSource.yourDataSourceName..

Where can I put these properties?

As mentioned, the canonical answer is in the MicroProfile Config specification. Here are just some of the places you can place configuration information.

META-INF/microprofile-config.properties classpath resource

Here's how it might look in the src/main/resources/META-INF/microprofile-config.properties configuration source:

javax.sql.DataSource.yourDataSourceName.somePropertyOfYourConnectionPoolAndDataSource = itsValue
javax.sql.DataSource.yourDataSourceName.someOtherPropertyOfYourConnectionPoolAndDataSource = anotherValue
System properties on the java command line

Here's how it might look as system properties instead:

java \
  -Djavax.sql.DataSource.yourDataSourceName.somePropertyOfYourConnectionPoolAndDataSource=itsValue \
  -Djavax.sql.DataSource.yourDataSourceName.someOtherPropertyOfYourConnectionPoolAndDataSource=anotherValue \
  # ...
Environment variables for your java executable set by your shell

Here's how it might look as environment variables as typed directly into a command line shell, taking advantage of MicroProfile Config's mapping rules, since many shells will not understand environment variable names with periods (.) in them:

JAVAX_SQL_DATASOURCE_YOURDATASOURCENAME_SOMEPROPERTYOFYOURCONNECTIONPOOLANDDATASOURCE=itsValue \
JAVAX_SQL_DATASOURCE_YOURDATASOURCENAME_SOMEOTHERPROPERTYOFYOURCONNECTIONPOOLANDDATASOURCE=anotherValue \
java # ...
Environment variables for your java executable set by the env shell command

Here's how it might look as environment variables as supplied via the env shell command, thus removing the need for MicroProfile Config's mapping rules and making things more efficient as a result:

env 'javax.sql.DataSource.yourDataSourceName.somePropertyOfYourConnectionPoolAndDataSource=itsValue' \
  'javax.sql.DataSource.yourDataSourceName.someOtherPropertyOfYourConnectionPoolAndDataSource=anotherValue' \
  java # ...
application.yaml classpath resources

Here's how it might look as YAML in a src/main/resources/application.yaml file (assuming the file is registered as a MicroProfile Config configuration source):

javax:
  sql:
    DataSource:
      yourDataSourceName:
        somePropertyOfYourConnectionPoolAndDataSource: itsValue
        someOtherPropertyOfYourConnectionPoolAndDataSource: anotherValue
Mix and match

Finally of course you can mix and match these approaches, taking advantage of MicroProfile Config's non-deterministic precedence rules, so that, for example, a data source property set as a system property will override one that may appear in src/main/resources/META-INF/microprofile-config.properties. There is nothing specific to data sources about how all this works.

For more on MicroProfile Config configuration sources, please see the relevant Helidon guide and/or the MicroProfile Config documentation.

Do you support Spring Boot configuration conventions out of the box?

No. Specifically, Helidon does not support application.properties out of the box as a source of external configuration. You can, of course, register a configuration source following the rules of the MicroProfile Config specification.

Can you give me a general example?

Not really. The actual property names are those your DataSource implementation actually supports, and can also vary depending on which connection pool you are using. You'll need to consult the specific examples below tailored to a combination of database driver and connection pool.

Can you give me a specific example of connecting to an Oracle database with a UCP-managed DataSource?

This example presumes that you have set up the Universal Connection Pool as described earlier in this document.

Here is an example in Java properties file format that configures a Universal Connection Pool-managed data source named main to connect to an Oracle Database on localhost port 1521 using the "thin" driver with a service name of XE with a user of scott and a password of tiger:

# (Why "connectionFactoryClassName"? See
# https://docs.oracle.com/en/database/oracle/oracle-database/21/jjuar/oracle/ucp/jdbc/PoolDataSourceImpl.html#setConnectionFactoryClassName_java_lang_String_)
javax.sql.DataSource.main.connectionFactoryClassName = oracle.jdbc.pool.OracleDataSource
javax.sql.DataSource.main.url = jdbc:oracle:thin://@localhost:1521/XE # see https://docs.oracle.com/en/database/oracle/oracle-database/21/jjdbc/data-sources-and-URLs.html#GUID-EF07727C-50AB-4DCE-8EDC-57F0927FF61A
javax.sql.DataSource.main.user = scott
javax.sql.DataSource.main.password = tiger
Can you give me a specific example of connecting to an H2 database with a HikariCP-managed DataSource?

This example presumes that you have set up the HikariCP connection pool as described earlier in this document.

Here is an example that configures a HikariCP-managed data source named test to connect to an in-memory H2 database named unit-testing with a user of sa and an empty password:

# Why "dataSourceClassName"? See
# https://github.com/brettwooldridge/HikariCP#essentials
javax.sql.DataSource.test.dataSourceClassName = org.h2.jdbcx.JdbcDataSource
# Why "dataSource."? See
# https://github.com/brettwooldridge/HikariCP/blob/HikariCP-5.0.0/src/main/java/com/zaxxer/hikari/util/PropertyElf.java#L47-L49
javax.sql.DataSource.test.dataSource.url = jdbc:h2:mem:unit-testing;DB_CLOSE_DELAY=-1 # see http://www.h2database.com/html/features.html#database_url
javax.sql.DataSource.test.dataSource.user = sa
javax.sql.DataSource.test.dataSource.password =
Is there a general pattern I can use to figure out how to set other properties on the Universal Connection Pool in particular?

Yes, but with some limitations and a number of problems.

The Universal Connection Pool exposes various properties as Java Bean properties. In general, if its pooling mechanism, the oracle.ucp.jdbc.PoolDataSourceImpl class (not to be confused with your DataSource implementation that it wraps!), has a public method that starts with set and takes a single String or int parameter (and a corresponding get-prefixed method that returns a value of the same type), you can cause that "setter" method to be invoked by setting an analogous property in your configuration.

For example, to cause the setMinPoolSize(int) method to be called (corresponding to the Java Beans property named minPoolSize), you can set the minPoolSize property for your named data source like so:

javax.sql.DataSource.main.minPoolSize = 1 # for example

One thing that can be confusing when using the Universal Connection Pool in particular is that the DataSource implementation it uses—oracle.ucp.jdbc.PoolDataSourceImpl—to wrap your DataSource implementation (to provide pooling machinery for it)—say, org.h2.jdbcx.JdbcDataSource—exposes some Java Beans properties that are destined both for your DataSource implementation and itself! (The description Java Bean property of oracle.ucp.jdbc.PoolDataSourceImpl is one such example: setting javax.sql.DataSource.yourDataSourceName.description = someDescription will cause the setDescription method of oracle.ucp.jdbc.PoolDataSourceImpl to be called, as well as the setDescription method of org.h2.jdbcx.JdbcDataSource.) Is this confusing? You bet! But it's entirely out of Helidon's control.

It is thus unavoidably hard to figure out which properties affect the pool itself, which affect your DataSource implementation (that the pool wraps), and which might affect both. So, for example, if you were to set the databaseName Java Beans property on the pool, it might also "forward" that to your DataSource implementation (if it supports that Java Bean property). But other Java Bean properties like, for example, maxIdleTime, are (one hopes!) properties of just the connection pooling mechanism itself, and (probably!) not of your DataSource implementation. Unfortunately, knowing which is which basically comes down to intuition, trial, and error.

Is there a general pattern I can use to figure out how to set other properties on the HikariCP connection pool in particular?

Yes. The HikariCP connection pool uses properties that are fully documented. Helidon's integration of the HikariCP connection pool prefixes these properties with its usual type-of-object string (javax.sql.DataSource.), followed by the name of your data source (yourDataSourceName.). So, for example, to set the HikariCP connection pool dataSourceClassName Java Bean property, you would set a corresponding MicroProfile Config property like so:

javax.sql.DataSource.yourDataSourceName.dataSourceClassName = org.h2.jdbcx.JdbcDataSource # for example

To set a Java Bean property on your DataSource implementation itself (for example, the loginTimeout Java Bean property of org.h2.jdbcx.JdbcDataSource), you prefix the property name with the usual Helidon prefix (javax.sql.DataSource.yourDataSourceName.), the HikariCP-reserved word dataSource., and the property name itself (loginTimeout):

javax.sql.DataSource.yourDataSourceName.dataSource.loginTimeout = 100 # for example

What value should I use for my connection pool's property that designates my DataSource class name?

Database Vendor DataSource class name UCP property example HikariCP property example
Oracle oracle.jdbc.pool.OracleDataSource javax.sql.DataSource.yourDataSourceName.connectionFactoryClassName = oracle.jdbc.pool.OracleDataSource javax.sql.DataSource.yourDataSourceName.dataSourceClassName = oracle.jdbc.pool.OracleDataSource
H2 org.h2.jdbcx.JdbcDataSource javax.sql.DataSource.yourDataSourceName.connectionFactoryClassName = org.h2.jdbcx.JdbcDataSource javax.sql.DataSource.yourDataSourceName.dataSourceClassName = org.h2.jdbcx.JdbcDataSource
PostgreSQL org.postgresql.ds.PGSimpleDataSource javax.sql.DataSource.yourDataSourceName.connectionFactoryClassName = org.postgresql.ds.PGSimpleDataSource javax.sql.DataSource.yourDataSourceName.dataSourceClassName = org.postgresql.ds.PGSimpleDataSource

JTA-Related Topics

My transaction is timing out. How can I increase the transaction timeout?

Helidon's JTA support is provided by Narayana. Setting Narayana's properties can be tricky.

To change the default transaction timeout by setting a system property, add this to your java command line:

# Specifies the default timeout for Narayana's transaction coordinator in seconds.
-Dcom.arjuna.ats.arjuna.coordinator.defaultTimeout=120

Thanks! I'm happy my transaction is taking so long that I have to increase the timeout.

You probably shouldn't be. Usually this means you haven't added the right indices to your database tables, or that your JPA query is manifesting the n + 1 problem. In any event, increasing the transaction timeout is almost always the wrong thing to do.

JPA-Related Topics

My persistence.xml has <property name="javax.persistence.jdbc.driver">

Stop right there. This is not a Helidon question. This is a question about application-managed JPA versus container-managed JPA. Helidon provides container-managed JPA integration, which means among many, many other things you don't specify JDBC information in your META-INF/persistence.xml file. You will want to read the specification for more details. Briefly, the entire point of container-managed JPA is that all of this stuff is taken care of for you, so your META-INF/persistence.xml classpath resource should mention a JTA-enabled data source name that should be used to connect to the database. See the other topics in this FAQ concerning data sources for some more information.

OpenAPI-related Topics

OpenAPI is the follow-on standard to Swagger for defining the external interface to REST services. MicroProfile OpenAPI supports OpenAPI via MP annotations, additional APIs, and the /openapi endpoint which serves the OpenAPI document for the service.

How do I add OpenAPI support to my Helidon MP application?

  1. Read our MP OpenAPI documentation here.
  2. Do what the doc says: update your pom.xml and add some annotations to your endpoints.

How do I add OpenAPI support to my Helidon SE application?

  1. Read our SE OpenAPI documentation here.

  2. Do what the doc says: update your pom.xml and choose a way to provide the OpenAPI information to Helidon.

    Unlike with MP, which uses annotation processing to find out for itself about your service's endpoints, you have to tell Helidon SE OpenAPI about your service's REST API. The documentation explains how you can do this either by providing a static OpenAPI file or by writing some code that creates the in-memory model for your API.

The MicroProfile OpenAPI-U/I extension

What is it?

The MP OpenAPI-U/I extension adds an endpoint to your service (provided you added the Helidon MP OpenAPI support) so you can use a browser to view your service's REST API and test drive it from that same web page.

How do I use the extension?

Add this dependency to your project

<dependency>
    <groupId>org.microprofile-ext.openapi-ext</groupId>
    <artifactId>openapi-ui</artifactId>
    <version>1.1.5</version>
</dependency>

being sure to use the current version of the extension.

Then access the automatically-provided endpoint /openapi-ui.

How do I fix No handler found for path: /openapi-ui?

You might have your own Application class which specifies @ApplicationPath("/mypath"). In that case, use /mypath/openapi-ui.

I did that. Now how do I fix No handler found for path: /mypath/openapi-ui?

Your Application class might override either getClasses or getSingletons. If so, make sure your getClasses implementation returns a set that includes not only your own resource classes but also these two from the extension: OpenApiUiService.class and StaticResourcesService.class. (Note also that at this point you are in Jersey land, not Helidon land, as with almost all web-related things in Helidon MP).

What if I want the context path prefix for /openapi-ui to be different from the one for my regular endpoints?

  1. If you do not already have one, create an Application class for your service's JAX-RS resources. Implement its getClasses method to return a Set containing all your service's resource classes. Do not include the two OpenAPI-U/I resources.
  2. Create another Application class for the OpenAPI-U/I resources. Specify the path prefix you want using @ApplicationPath("myapi"). (Of course, use whatever path prefix you want.) Write getClasses to return a Set containing the two OpenAPI-U/I resource classes. Do not include your service's regular resource classes.

Now access the U/I at /myapi/openapi-ui. Of course, use the prefix you actually specified in the @ApplicationPath annotation for the OpenAPI-U/I Application class.

The OpenAPI-U/I displays a mostly empty page, with just a logo.

Currently, the application path for the app containing the OpenAPI U/I components must be only one segment long. For example, /foo works but /foo/bar does not. It seems the U/I extension cannot fetch some of its resources correctly with the longer app path. Still investigating, but until we know more just use one segment in the path.

Is That It?

No. This is just where this document currently ends. Enjoy your day!