jakarta-eeinstrumentationactivejdbcjavalite

ActiveJDBC instrumentation in ActiveJDBC 3.0 for Java 17 takes too long in big models


for business purposes i have to upgrade some backend's from java 8 + java-ee to java 17 + jakarta-ee. Those backends uses a single model (a large one, 800+ classes) and works just fine with activejdbc-2.4-j8 and the instrumentation time for that model is about 1 minute.

I manage to upgrade the model to java 17 + activejdbc-3.0 and get the compilation, so the backends is now working as expected in java 17 + jakarta and uses the model with Activejdbc-3.0.

The main problem is that the dynamic instrumentation takes about 5 minutes to complete...

Some ideas to reduce that time? Is it posible?

-- EDIT 13 nov

Maven version: 3.9.3

Here is the instrumentation plugin for runtime:

<plugin>
  <groupId>org.javalite</groupId>
  <artifactId>activejdbc-instrumentation</artifactId>
  <version>3.0</version>
  <configuration>
    <generateStaticMetadata>false</generateStaticMetadata> 
  </configuration>
  <executions>
     <execution>
        <phase>process-classes</phase>
        <goals>
          <goal>instrument</goal>
        </goals>
     </execution>
   </executions>
</plugin>

There is no relevant logs, the app is working as spected. Just the huge delay on the first run. The instrumentation in the first run is about 5 minutes.

Also, i tried the instrumentation at build time. It also works, much faster.

Here is the instrumentation plugin:

<plugin>
  <groupId>org.javalite</groupId>
  <artifactId>activejdbc-instrumentation</artifactId>
  <version>3.0</version>
  <configuration>
    <generateStaticMetadata>true</generateStaticMetadata> 
    <databases>
      <database>
        <name>default</name>
        <url>${jdbc.url}</url>
        <username>${jdbc.user}</username>
        <password>${jdbc.pass}</password>
        <driver>${jdbc.driver}</driver>
      </database>
    </databases>
  </configuration>
  <executions>
     <execution>
        <phase>process-classes</phase>
        <goals>
          <goal>instrument</goal>
        </goals>
     </execution> 
   </executions>
   <dependencies>
     <dependency>
       <groupId>org.postgresql</groupId>
       <artifactId>postgresql</artifactId>
       <version>42.6.0</version>
     </dependency>
   </dependencies>
</plugin>

The thing is that we work with several diferent enviroments with not always te same database scheme (develop, preproducction and production) and change the database configuration in each build to test in each enviroment is not to maintainable in this case.

The runtime instrumentation is to comeback in future versions?

Thanks


Solution

  • Edited based on added info in the question, Nov 13 2023

    The Instrumentation of models is something that changes their bytecode after compilation at build time (Dymanic instrumentation does this at the start of a process). You use instrumentation at build time according to your configuration.

    What you are using is called Dynamic Discovery, and is a process for models to find each other's relationships at the start of the process, based on naming conventions and DB schema.

    It is the Dynamic Discovery, not instrumentation that takes time for you. If this works fast on one database and slow on the other, you may need to look into user permissions on that database (as it pertains to querying the schema).

    Additionally, if you add (and you already did) this:

    <generateStaticMetadata>true</generateStaticMetadata>
    

    this will perform the discovery at build time based on the local database, reducing the start at runtime.

    It is hard to imagine that the same codebase will work against different database schemas with or without JavaLite.

    In other words, if your database schema across various environments is different, you may have unpredictable issues. I suggest that you have the same schema across the environments, and generate the metadata at build time. In that case, ActiveJDBC will initialize instantly at the start of the process.