Skip to content

internal_howto_build

etienne-sf edited this page Jun 22, 2024 · 24 revisions

You'll find here all the needed information to properly build the project.

Prerequisite

  • The needed Java version is 17
    • But the build result (the plugin) is compatible with Java 8
    • Java 17 is needed to :
      • Build the Forum's samples: they are build against Spring Boot 3, and therefore they need Java 17
      • Build the Gradle graphql-gradle-plugin3, that is compiled against Spring Boot 3
  • When using an IDE, you need to install Lombok, see below for the details

Project organization

Maven build

The maven build is the heart of the plugin. It contains:

  • The dependencies necessary to execute the generated code
  • The plugin's logic
  • Several samples, that are used both as samples, and for integration tests. All these samples are within the graphql-maven-plugin-samples folder. There are three main samples:
    • allGraphQLCases is based on a GraphQL schema the contains lots of various use cases, hence its name. The use cases added to test specific issues are in this project. The GraphQL schema file is stored in a unique place for all Maven modules: graphql-maven-plugin-samples/graphql-maven-plugin-samples-allGraphQLCases-client/src/graphqls/allGraphQLCases.
    • Forum is a sample for a posting boards, with Board, Topic, Post and Member objects
    • StarWars is a sample based on the StarWars sample found on the net (Droid, Human, Character...). Its server part is run as was on tomcat (whereas the other are Spring Boot executables)

This a muti-module projects. The modules are (in build order)

  • graphql-maven-plugin-project: The root pom. It contains the pages for the site, and its pom contains the declaration for every dependency and plugin version.
  • graphql-java-client-dependencies: This project is just a pom, that contains the dependencies for the client mode.
  • graphql-java-server-dependencies: This project is just a pom, that contains the dependencies for the server mode.
  • graphql-java-common-runtime: This project contains runtime code that is common to both client and server mode.
  • graphql-java-client-runtime and graphql-java-server-runtime: This project contains the code that is necessary at runtime, for both client and for server mode. Its source is copied along with the generated source, so that no dependency from graphql-java-generator is necessary at runtime. And this insures that the runtime is of the good version, as expected by the generated code.
  • graphql-maven-plugin-logic: The heart of the plugin. This project contains the code that parses the GraphQL schema, then generates the code. It's reused for the Maven plugin and the Gradle plugin.
  • graphql-maven-plugin: This project embeds the graphql-maven-plugin-logic into a Maven plugin.
  • graphql-maven-plugin-samples: Just a container for all the samples for this project. All these projects are both samples and integration tests. For each sample, there is a server and a client. The client project depends on the server one: the integration tests are in the client project. The client project starts the server, then execute integration tests against it.
  • graphql-maven-plugin-samples-allGraphQLCases-server. This project is more used as integration test than a real sample, as there is no real functionality. It contains various combinations that allow to validate the generated code, especially the AllGraphQLCases type. It also contains some Custom Scalars. The server is package as a Spring Boot application, and is executed on a http URL.
  • graphql-maven-plugin-samples-allGraphQLCases-client. This project allows to test complex behaviors on client side, especially the AllGraphQLCases type. It contains integration testing that starts the associated server, then connect to it.
  • graphql-maven-plugin-samples-CustomTemplates-client: it demonstrates the use of custom templates. One custom template is packaged in the jar produced by graphql-maven-plugin-samples-CustomTemplates-resttemplate. The other is in the src/main/graphql/customtemplates folder
  • graphql-maven-plugin-samples-CustomTemplates-resttemplate: it packages a custom template in a jar, that is then used by the graphql-maven-plugin-samples-CustomTemplates-client.
  • graphql-maven-plugin-samples-Forum-server. This project is a GraphQL API to manage a simple forum. It embeds an in memory database, that is filled at startup time with simulated data. This data is also used in the integration tests in the client, see below. It contains a sample for Custom Scalar and for Schema personalization (you can change the generated objects through a personalization file). The server is package as a Spring Boot application, and is executed on a http URL.
  • graphql-maven-plugin-samples-OAuth-authorization-server. It contains a sample and simplified OAuth2 server. It allows the allGraphQLCases sample (server and client) to work with OAuth2. So, the code (main and test) of the allGraphQLCases-client sample are all based on an OAuth2 authorization server.
  • graphql-maven-plugin-samples-Forum-client. Demonstration for Custom Scalar
  • graphql-maven-plugin-samples-StarWars-server. The server is package as a WAR application, and is executed on a https URL.
  • graphql-maven-plugin-samples-StarWars-client. For integration tests, the WAR server is started into a tomcat, and exposed as an https URL.

Gradle build

The Gradle build reuses the plugin's logic coming from the Maven graphql-maven-plugin-logic. It encapsulate so that this logic can be used as a Gradle plugin.

It contains the allGraphQLCases and Forum samples, whose code is a copy of the code of the relevant Maven module. So the integration tests for these samples, that are executed when building the Gradle project, are exactly the same code. The code from the Maven modules is copied into the Gradle project by the copySamplesFromMavenPlugin Gradle task. See the HowTo Release page for more information The only difference is the plugin configuration, that is defined in the build.gradle file, instead of the Maven pom.xml file.

The gradle build generates two plugins:

  • The graphql-gradle-plugin is built against java 8 for Spring Boot 2 and Spring Framework 5
  • The graphql-gradle-plugin3 is built against java 17 for Spring Boot 3 and Spring Framework 6

HowTo compile

Lombok

Lombok is an excellent tool that generated getters, setters, constructors (and mode) from one annotation. The plugin code uses it a lot, to make the code lighter and easier to read.

Caution: you should use version 1.18.24 or above, to avoid issues with eclipse.

You need to install lombok, for your favorite IDE:

Note: The generated code doesn't use Lombok.

Compile the samples

The project should have been imported into your IDE.

If not, check why your IDE didn't properly import a multi-module Maven project.

If you properly configured Lombok (see here above), everything should compile, out of the samples.

To compile the samples (at least with eclipse), you need to add the generated code in the build path, as the project code uses it.

  • Start with a full build (mvn clean install), to be sure all modules are Ok, then:
  • For eclipse:
    • Open the Project explorer view,
    • Navigate to the target folder of the sample you want to compile,
    • right click on the target/generated-sources/graphql-maven-plugin folder,
    • Choose Build Path / USe to Source Folder.
    • Alternatively, you can open the project properties, and update directly the Build Path there.
    • Note: if you compile the project from a terminal window (outside eclipse), and eclipse is configure to refresh the project "with native hooks", it can happen that eclipse interferes with the build. This generates strange bugs when building the plugin-logic module. You'll then have to deactivate the automatic build (menu Project / Build Automaticaly) during the external build
  • For other IDE: please fork the project on github, and provide a Pull Request with the relevant doc.

Full local build

Just Maven

To have a full build of the Maven part, it's standard and easy:

  • Check out the Maven project
  • Run the mvn clean install command

Both Maven and Gradle

To have a full build of the plugin, including the Gradle part, you need to build both the Maven and the Gradle projects. And the two must be linked.

Here are the steps to do this:

  • Check out the Maven project
  • Run the mvn clean install command
  • Check out the Gradle project
  • Update the graphql-gradle-plugin/common_conf.gradle file:
    • Change the version property to local-SNAPSHOT. This will make the Gradle build use the artefacts generated locally from the Maven build.
  • Run the gradlew build command. This will build the plugin, then all the samples, and run the integration tests.

When working on a full build (Gradle+Maven), it may happen that you have to update the integration tests, in the Maven project. Doing this may break the Gradle build, or at least, the newly created test won't be in the Gradle build. To copy into the Gradle project the whole code from the allGraphQLCases and Forum samples from the relevant Maven modules, do this:

  • Update your main Gradle configuration file (.gradle/gradle.properties) file:
    • Define the systemProp.graphqlGradlePlugin.graphqlMavenPluginProject.path property, with the absolute path of the Maven project.
    • Note: a future version should make it easier, by just expecting all git projects to be stored in the same folder.
  • Go to the Gradle project folder
  • Execute this command: gradlew copySamplesFromMavenPlugin
  • Then a gradlew clean build allows to execute the whole Gradle project, including the integration tests that where developed in the Maven module.

Help for debugging

View server output

To avoid polluting the maven output, the default log configuration file sent all the output into the log file. You can check that in the /src/main/resources/logback.xml file.

Another file is available, that shows more information, and output it on the console: /src/main/resources/logback-local.xml

To have all the output in the console (very useful when testing), you can start the GraphQLServerMain with this JVM parameter:

GraphQLServerMain -Dlogging.config=classpath:logback-local.xml

Some tricks with gradle and eclipse

Update the Gradle dependency version to the maven plugin logic (even when this induce compilation error)

Eclipse seems to be unable to update the dependencies, when there is a compilation error. Unfortunately, this happens from time to time when updating the graphql-maven-plugin-logic version: if they are new plugin parameters, then as they are not defined yet in the gradle project, they are compilation errors, and the build path is not refreshed properly.

To still update the build path, with the new plugin logic version (or other dependencies), you can try the proposals from this answer:

  • gradle cleanEclipse
    • Possibly:
    • gradle cleanEclipseProject
    • gradle cleanEclipseClasspath
  • gradle eclipse

This works even without applying the eclipse plugin in the build.gradle file.

In an independent gradle project, use a local version of the plugin

The Gradle project is a composite build that contains the two plugins versions (for Spring Boot 2.x and 3.x), and the samples, copied from the maven projet, mainly for integration tests.

But it happens that a specific gradle configuration must tested (for instance, when doing support, to check for a correction on a specific project that has an issue with the plugin).

Unlike maven, this complicated to do with Gradle.

The below links give different ways to do this:

Here is a sample:

buildscript {
    ext {
        springBootVersion = '3.2.6'
        springCoreVersion = '6.1.8'
        springSecurityVersion = '6.2.4'
		// graphQLPluginVersion = '2.4'
		graphQLPluginVersion = 'local-SNAPSHOT' // For use of the local plugin's version
    }
    repositories {
        mavenLocal()
        mavenCentral()
    }
    dependencies { // For use of the local plugin's version
        classpath files('../graphql-gradle-plugin-project/graphql-gradle-plugin3/build/libs/graphql-gradle-plugin3-local-SNAPSHOT.jar')
		// This plugin is a wrapper of the logic already implemented in our maven plugin
		classpath ("com.graphql-java-generator:graphql-maven-plugin-logic:${graphQLPluginVersion}") {
			exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
			exclude group: 'org.slf4j', module: 'slf4j-api'
			exclude group: 'net.minidev', module: 'json-smart'
		}
		classpath "org.springframework:spring-context:${springCoreVersion}"
	}
}

plugins {

...
	
	// The below line is commented to allow the use of the local plugin's version
    // id "com.graphql-java-generator.graphql-gradle-plugin3" version "${graphQLPluginVersion}"
}

// For use of the local plugin's version (use the fully qualified classname
apply plugin: com.graphql_java_generator.gradleplugin.GraphQLPlugin

repositories {
	mavenLocal()  // For use of the local plugin's version
	mavenCentral()
}

Issues with git

Issues with git configuration

Lots of responses in the forum indicate that the following command allows to store the login and password in the ~/.git-credentials file:

git config --global credential.helper store

then

git remote set-url origin https://{new url with username replaced}

This should add lines like the two below in the ~/.git-credentials file (don't know if both are really necessary):

https://login:[email protected]/
https://login:[email protected]

I add no luck doing that. But the below command allowed to properly connect to github:

git config --global credential.helper cache
Clone this wiki locally