etiennestuder / gradle-jooq-plugin Goto Github PK
View Code? Open in Web Editor NEWGradle plugin that integrates jOOQ.
License: Apache License 2.0
Gradle plugin that integrates jOOQ.
License: Apache License 2.0
If I change database table structure, say add new column (I use postgres), and run
gradlew generateMainJooqSchemaSource
then it says
:generateMainJooqSchemaSource UP-TO-DATE
, which means it doesn't change anything in generated code (it doesn't indeed).
The only workaround now is to delete the generated files before running the build.
It would be nice to have it recognize database structure changes, or at least to have another gradle task which forces code re-generation.
Hello,
In JOOQ 3.9.0 (https://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd) it is possible to add the javaTimeTypes property, to incorporate the new Java 8 date-time api. Unfortunately the plugin seems to falsely say the property is wrong:
buildscript {
ext {
jooqVersion = "3.9.1"
}
dependencies {
classpath('nu.studer:gradle-jooq-plugin:2.0.2')
}
}
jar {
baseName = 'planner-jooq'
version = appVersion
}
dependencies {
compile("org.jooq:jooq:${jooqVersion}")
}
if (project.hasProperty('genJooq')) {
apply plugin: 'nu.studer.jooq'
dependencies {
jooqRuntime("org.postgresql:postgresql:${postgresJdbcVersion}")
}
jooq {
version = jooqVersion
edition = 'OSS'
sample(sourceSets.main) {
jdbc {
driver = 'org.postgresql.Driver'
url = 'jdbc:postgresql://localhost:5432/planner'
user = '****'
password = '****'
}
generator {
name = 'org.jooq.util.DefaultGenerator'
strategy {
name = 'org.jooq.util.DefaultGeneratorStrategy'
// ...
}
database {
name = 'org.jooq.util.postgres.PostgresDatabase'
inputSchema = 'public'
// ...
}
generate {
relations = true
deprecated = false
records = true
javaTimeTypes = true // THIS IS NOT WORKING
// immutablePojos = true
// fluentSetters = true
// ...
}
target {
packageName = 'nl.mjsoft.planner.jooq'
directory = 'src/main/java'
}
}
}
}
}
Output:
Build file '/...../build.gradle' line: 51
* What went wrong:
A problem occurred evaluating project ':jooq'.
> Invalid property: 'javaTimeTypes' on extension 'jooq.sample.generator.generate', value: true
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 2.768 secs
Run Gradle plugin with Java 9, task "generate"
> Task :generateJooqSchemaSource
Error: Unable to initialize main class org.jooq.util.GenerationTool
Caused by: java.lang.NoClassDefFoundError: javax/xml/bind/ValidationEventHandler
Upgraded my plugin fr 2.0.4 to 2.0.6 (jooq 3.9.1 & 3.9.2 both tested)
:generateAPJooq
SchemaSourceMay 04, 2017 7:24:30 AM org.jooq.tools.JooqLogger info
INFO: Initialising properties : E:\src\ap\build\tmp\jooq\config.xml
May 04, 2017 7:24:30 AM org.jooq.tools.JooqLogger warn
WARNING: Unmarshal warning : cvc-complex-type.2.4.a: Invalid content was found starting with element 'varargSetters'. One of '{"http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd":fullyQualifiedTypes, "http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd":emptyCatalogs, "http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd":emptySchemas, "http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd":javaTimeTypes}' is expected.
May 04, 2017 7:24:30 AM org.jooq.tools.JooqLogger warn
WARNING: Unmarshal warning : unexpected element (uri:"http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd", local:"varargSetters"). Expected elements are <{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}queues>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}fluentSetters>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}globalSequenceReferences>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}pojos>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}pojosEqualsAndHashCode>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}globalTableReferences>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}springAnnotations>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}javaTimeTypes>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}relations>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}routines>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}udts>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}immutablePojos>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}globalQueueReferences>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}emptySchemas>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}interfaces>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}validationAnnotations>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}globalUDTReferences>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}immutableInterfaces>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}instanceFields>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}pojosToString>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}tables>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}globalRoutineReferences>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}links>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}globalLinkReferences>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}deprecated>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}jpaAnnotations>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}records>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}fullyQualifiedTypes>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}globalCatalogReferences>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}daos>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}generatedAnnotation>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}emptyCatalogs>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}globalObjectReferences>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}sequences>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.0.xsd}globalSchemaReferences>
I would prefer that only the named package got deleted by 'gradle clean'. I had non-generated but related code (extensions which wrap dependent tables and such) in a directory parallel with the top package.
My config had target {dir = src/jooq/java; package = edu.uni.lab.db.generated} with my extensions in edu.uni.lab.db.crafted.
I have since moved that package to another sourceset but I feel it's now misplaced.
The following problem is thrown during the configuration phase:
Could not find matching constructor for: java.util.List()
The problem arises in "BridgeExtension" Line 42 when instantiating the return type of "schemata" which is java.util.List. Obviously java.util.List can not be created...
I have a the following configuration. Is it malformed or is this a bug of the plugin?
jooq {
sample(sourceSets.main) {
jdbc {
driver = 'org.hsqldb.jdbc.JDBCDriver'
url = ...
}
generator {
database {
name = 'org.jooq.util.hsqldb.HSQLDBDatabase'
schemata {
schema {
inputSchema = 'SCHEMA1'
outputSchema = 'SCHEMA1'
}
schema {
inputSchema = 'SCHEMA2'
outputSchema = 'SCHEMA2'
}
...
}
}
}
}
I am having a super hard time finding the right gradle syntax to represent the XML found at: http://www.jooq.org/doc/3.8/manual-single-page/#custom-data-types
Specifically the customTypes with the customType.
Here is what I have that is totally not working:
database {
name = 'org.jooq.util.postgres.PostgresDatabase'
inputSchema = 'public'
customTypes = [
customType {
name = 'JsonElement'
type = 'com.google.gson.JsonElement'
binding = 'com.closient.jooq.util.PostgresJSONGsonBinding'
}
]
forcedTypes = [
forcedType {
name = 'JsonElement'
expression = '.*JSON.*'
types = '.*'
}
]
}
I place my generated files inside src and commit them to version control. So I have a config like this:
jooq {
main {
...
generator {
...
target {
packageName = 'com.company.service.db'
directory = 'src/main/java'
}
}
}
}
This way my files are generated in src/main/java/com/company/service/db
However when I run the clean task, which triggers this plugin's cleanGenerateMainJooqSchemaSource
task, it deletes src/main/java
, which isn't desireable..
Hey, sorry I wasn't sure where to ask questions regarding the plugin.
We're using postgres as our datastore, with > 500 schemas, so am guessing to use JOOQ I'd need separate models created for every schema? So was wondering if there's a way to provide a regular expression in the inputSchema
field of generator > database in my gradle config?
Thanks for creating this awesome project :)
Using buildscript
to load the jooq dependencies has several problems:
plugins
instead of buildscript
buildscript
also contains all other libraries on the script's classpathInstead the plugin should add a dependency configuration and load jooq dynamically from there:
dependencies {
jooqGenerator 'some-version-of-jooq'
jooqGenerator 'some-db-driver'
}
Another advantage is that this way it would be trivial to add a forked mode for when users need more control over the generation process.
I created a dead simple project following your configuration instructions:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'nu.studer:gradle-jooq-plugin:1.0.5'
classpath 'net.sourceforge.jtds:jtds:1.3.1'
}
}
repositories {
mavenCentral()
}
apply plugin: 'nu.studer.jooq'
dependencies {
compile' org.jooq:jooq:3.4.1'
compile 'com.jolbox:bonecp:0.8.0.RELEASE'
}
jooq {
sample(sourceSets.main) {
jdbc {
driver 'net.sourceforge.jtds.jdbc.Driver'
url 'xxx'
user 'xxx'
password 'xxx'
schema 'dbo'
}
generator {
database {
name 'org.jooq.util.ase.ASEDatabase'
inputSchema 'dbo'
excludes 'sys.*'
}
generate {
deprecated false
}
target {
packageName 'com.lucmazon.jooq.generated'
}
}
}
}
But whenever I try to execute any task (say gradle tasks
), it results in the following error:
* What went wrong:
A problem occurred evaluating root project 'jooqGradle'.
> Could not find method sample() for arguments [source set 'main', build_74koem9eubtemc80ae1njj80qc$_run_closure3_closure4@1e0f3b57] on root project 'jooqGradle'.
From what I understand reading your documentation, we can have multiple configurations, and we're trying here to create one named "sample". Is there somewhere else I should declare it (I'm quite new to gradle)?
Here are my gradle informations:
------------------------------------------------------------
Gradle 1.12
------------------------------------------------------------
Build time: 2014-04-29 09:24:31 UTC
Build number: none
Revision: a831fa866d46cbee94e61a09af15f9dd95987421
Groovy: 1.8.6
Ant: Apache Ant(TM) version 1.9.3 compiled on December 23 2013
Ivy: 2.2.0
JVM: 1.7.0_51 (Oracle Corporation 24.51-b03)
OS: Linux 3.13.0-20-generic amd64
Thanks!
First of all, great plugin. Really simplifies usage of JOOQ code generation.
We would like to use this plugin by just calling the generated task but not during the build process of a project. Is there a way to disable the build dependencies defined in: https://github.com/etiennestuder/gradle-jooq-plugin/blob/master/src/main/groovy/nu/studer/gradle/jooq/JooqPlugin.groovy#L114 ?
I am trying to use a custom jOOQ generator class to alter the generate source code, but when I run with the class specified I am getting the following:
java.lang.ClassNotFoundException: us.hexcoder.CustomJooqGeneratorStrategy
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.jooq.util.GenerationTool.loadClass(GenerationTool.java:492)
at org.jooq.util.GenerationTool.run(GenerationTool.java:231)
at org.jooq.util.GenerationTool$run.call(Unknown Source)
at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:45)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:108)
at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:116)
at nu.studer.gradle.jooq.JooqTask.generate(JooqTask.groovy:38)
I have written up a StackOverflow post describing the situation, but am not getting any luck with the issue. Given that I'm not quite sure where the issue lies at this point (in my Gradle configuration, in this plugin, or in jOOQ) I'm posting here as well. I have also have a minimal recreation of the issue up on GitHub - you'll need to create a Postgres DB with the credentials in the build.gradle
file, but running gradle jar
will achieve the exception. Looking through the logs with the --debug
switch, it looks like the JAR is in fact being picked up:
19:13:28.857 [DEBUG] [org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.DependencyGraphBuilder] Visiting dependency :test-jooq:unspecified(classpath) -> :test-jooq-generator:(dependency: #test-jooq-generator; {classpath=[default]})
19:13:28.858 [DEBUG] [org.gradle.api.internal.artifacts.ivyservice.resolveengine.graph.DependencyGraphBuilder] Selecting new module version :test-jooq-generator:
19:13:28.858 [DEBUG] [org.gradle.api.internal.artifacts.ivyservice.ivyresolve.RepositoryChainDependencyResolver] Attempting to resolve :test-jooq-generator: using repositories [BintrayJCenter, MavenRepo, flatDir]
19:13:28.858 [DEBUG] [org.gradle.api.internal.artifacts.ivyservice.ivyresolve.CachingModuleComponentRepository] Detected non-existence of module ':test-jooq-generator:' in resolver cache 'BintrayJCenter'
19:13:28.859 [DEBUG] [org.gradle.api.internal.artifacts.ivyservice.ivyresolve.CachingModuleComponentRepository] Detected non-existence of module ':test-jooq-generator:' in resolver cache 'MavenRepo'
19:13:28.862 [DEBUG] [org.gradle.api.internal.artifacts.repositories.resolver.DefaultExternalResourceArtifactResolver] Loading file:/private/tmp/test-jooq/lib/test-jooq-generator-.jar
19:13:28.863 [DEBUG] [org.gradle.api.internal.artifacts.repositories.resolver.DefaultExternalResourceArtifactResolver] Loading file:/private/tmp/test-jooq/lib/test-jooq-generator.jar
19:13:28.866 [DEBUG] [org.gradle.api.internal.artifacts.repositories.resolver.ExternalResourceResolver] Found artifact but no meta-data for module ':test-jooq-generator:' in repository 'flatDir', using default meta-data.
19:13:28.866 [DEBUG] [org.gradle.api.internal.artifacts.ivyservice.ivyresolve.RepositoryChainDependencyResolver] Using :test-jooq-generator: from Ivy repository 'flatDir'
Any pointers?
Hi,
As on the project I'm in we are already using Hibernate with JPA, I want to use the JPA translation features of JOOQ. I'm using JOOQ version 3.9.0
When I try to build, I get the following error:
Error : org.jooq.util.jpa.JPADatabase
java.lang.ClassNotFoundException: org.jooq.util.jpa.JPADatabase
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at org.jooq.util.GenerationTool.loadClass(GenerationTool.java:668)
at org.jooq.util.GenerationTool.run(GenerationTool.java:294)
at org.jooq.util.GenerationTool.generate(GenerationTool.java:199)
at org.jooq.util.GenerationTool.main(GenerationTool.java:171)
Although I know the class is in there, included by the jooq-meta-extensions dependency.
This is my jooq plugin configuration:
jooq {
version = '3.9.0'
edition = 'OSS'
basic(sourceSets.main) {
generator {
database {
name = 'org.jooq.util.jpa.JPADatabase'
properties {
property {
key = 'packages'
value = 'myapp.entities'
}
}
}
}
}
}
Am I missing something? or does the plugin has issues using the JOOQ JPA integration feature?
Thanks
I would like to compile a single class, an Annotator, before running the code generator. I tried 'jooq (dependsOn: annoTask)' and 'jooq{doFirst(annoTask)}' but neither parses. Is there a way to make jooq dependent on some other part of the build.
Currently I have the class in a separate jar but that seems over kill.
I am very new in gradle and android, i followed the instructions but i keep getting:
Error:Gradle DSL method not found: 'sample()'
Hi,
Very odd set of warnings:
I have the gradle plugin
id 'nu.studer.jooq' version '2.0.9'
using Jooq 3.10.2 OSS edition
and if I check the generated config.xml it shows:
$ cat build/tmp/jooq/config.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?><configuration xmlns="http://www.jooq.org/xsd/jooq-codegen-3.10.0.xsd">....
However during code generation gives warnings referring to 3.9.2.xsd??
Dec 11, 2017 10:27:21 AM org.jooq.tools.JooqLogger warn
WARNING: Unmarshal warning : unexpected element (uri:"http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd", local:"includeIndexes"). Expected elements are <{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}recordVersionFields>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}includePrimaryKeys>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}includeExcludeColumns>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}overridePrimaryKeys>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}recordTimestampFields>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}schemaVersionProvider>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}inputCatalog>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}inputSchema>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}syntheticIdentities>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}syntheticPrimaryKeys>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}outputSchema>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}includeTables>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}excludes>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}includePackages>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}includeUniqueKeys>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}dateAsTimestamp>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}catalogVersionProvider>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}regexFlags>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}forcedTypes>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}catalogs>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}outputCatalog>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}includeUDTs>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}includeSequences>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}customTypes>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}tableValuedFunctions>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}properties>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}name>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}outputSchemaToDefault>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}ignoreProcedureReturnValues>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}includeRoutines>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}schemata>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}outputCatalogToDefault>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}includeForeignKeys>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}unsignedTypes>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}includes>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}enumTypes>
Dec 11, 2017 10:27:21 AM org.jooq.tools.JooqLogger warn
WARNING: Unmarshal warning : unexpected element (uri:"http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd", local:"orderProvider"). Expected elements are <{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}recordVersionFields>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}includePrimaryKeys>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}includeExcludeColumns>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}overridePrimaryKeys>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}recordTimestampFields>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}schemaVersionProvider>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}inputCatalog>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}inputSchema>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}syntheticIdentities>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}syntheticPrimaryKeys>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}outputSchema>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}includeTables>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}excludes>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}includePackages>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}includeUniqueKeys>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}dateAsTimestamp>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}catalogVersionProvider>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}regexFlags>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}forcedTypes>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}catalogs>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}outputCatalog>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}includeUDTs>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}includeSequences>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}customTypes>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}tableValuedFunctions>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}properties>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}name>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}outputSchemaToDefault>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}ignoreProcedureReturnValues>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}includeRoutines>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}schemata>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}outputCatalogToDefault>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}includeForeignKeys>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}unsignedTypes>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}includes>,<{http://www.jooq.org/xsd/jooq-codegen-3.9.2.xsd}enumTypes>
The generated POJOs and classes representing tables have the same class name, which is tedious when you need to use both. Could you post a minimal example of how to add prefix or suffix to the generated table classes?
At least I haven't seen how to do it. I've tried a couple of list constructs in inputSchema and I've tried to iterate over a list of schema names. Is the only alternative to duplicate the jooq{} block for each schema?
I'm trying to configure the JOOQ generator to use camel-case for the generated POJOs. Using https://www.jooq.org/doc/3.9/manual/code-generation/codegen-matcherstrategy/ as a guide I've tried using the following syntax:
generator {
name = 'org.jooq.util.DefaultGenerator'
strategy {
name = 'org.jooq.util.DefaultGeneratorStrategy'
matchers {
tables {
table {
tableClass {
transform = "CAMEL"
}
}
}
}
}
}
But I get the following exception:
javax.xml.bind.MarshalException
- with linked exception:
[org.xml.sax.SAXParseException; lineNumber: 0; columnNumber: 0; cvc-complex-type.2.4.d: Invalid content was found starting with element 'matchers'. No child element is expected at this point.]
Am I going about this the wrong way? Or is it not supported in this plugin?
A jOOQ user is running into issues because a very old jOOQ version is being pulled by this Gradle plugin. The issue is documented here:
http://stackoverflow.com/q/38727927/521799
Essentially:
dependencies {
...
// Expected jOOQ version
compile "org.jooq:jooq:3.8.4"
compile "org.jooq:jooq-meta:3.8.4"
compile "org.jooq:jooq-codegen:3.8.4"
}
...
buildscript {
repositories {
jcenter()
}
dependencies {
// Overridden jOOQ version: 3.4.1
classpath 'nu.studer:gradle-jooq-plugin:1.0.5'
...
}
}
gradle-jooq-plugin
to detect if jOOQ is already a dependency, and then use that version rather than the default?gradle-jooq-plugin
currently log the fact that it is using an old / hard-wired version?Did not intend to create an issue, but this seems to be the only way to communicate with authors. I had some trouble using this plugin with the kotlin-dsl, and also noticed an issue that was closed in this repo mentioning similar troubles. For those reasons, I have created a plugin for kotlin-dsl: https://github.com/rohanprabhu/kotlin-dsl-gradle-jooq-plugin that allows type-safe usage.
The reason I am posting this here is because I drew massive inspiration from this plugin, and I have kept most of the concepts similar, in terms that we have tried to emulate the style as much as possible of this plugin. I have credited the same in the README and would like your comments on the same.
And when I say "massive inspiration", I pretty much learnt how to write a gradle plugin reading your code :)
Regards,
rohan
I am seeing semi-reliable false negatives in up-to-dateness detection of the source generation task. Running gradle with --info
shows this:
Executing task ':generateSampleJooqSchemaSource' (up-to-date check took 0.012 secs) due to:
Value of input property 'configHash' has changed for task ':generateSampleJooqSchemaSource'
Needless to say, I am not actually changing the configuration between runs.
Output of gradle --version
:
Gradle 3.5
------------------------------------------------------------
Build time: 2017-04-10 13:37:25 UTC
Revision: b762622a185d59ce0cfc9cbc6ab5dd22469e18a6
Groovy: 2.4.10
Ant: Apache Ant(TM) version 1.9.6 compiled on June 29 2015
JVM: 1.8.0_131 (Oracle Corporation 25.131-b11)
OS: Linux 4.11.3-1-ARCH amd64
The new (version 2.0) plugin seem to treat all dependencies with group org.jooq
as part of the jOOQ product package. This breaks other projects like jOOL.
Relevent parts of my build.gradle
:
dependencies {
jooqRuntime 'org.mariadb.jdbc:mariadb-java-client:1.5.1-RC'
compile "org.jooq.pro:jooq"
compile 'org.jooq:jool:0.9.11'
}
jooq {
version = '3.8.4'
edition = 'PRO'
...
}
If I list the dependencies:
...
+--- org.jooq.pro:jooq: -> 3.8.4
+--- org.jooq:jool:0.9.11 -> org.jooq.pro:jool:3.8.4 FAILED
...
Only the artifact with name 'jooq' (I think, maybe @lukaseder could confirm) should be modified by the plugin.
Hello,
It would be nice to have the option to disable schema generation on compileJava. I wrote a workaround using this code, which works but i'm afraid the schema would eventually get updated on the CI server (if we mistakenly rename the schema name "demo'" and forget to change the compileJava code, for example). In my case, I only want this tool available in the dev environment.
compileJava {
//This prevents the jooq data model from being generated automatically every time gradle
//compiles java code.
compileJava.taskDependencies.values -= "generateDemoJooqSchemaSource"
}
On another note, thanks for the plugin, works like a charm!
shaun
Is it possible to configure the gradle build script with multiple databases?
The way our project is structured we are doing something really wacky (personally I'm not a fan but I don't have time to fix it right now).
We launch our project structure as it is so our JPA's get loaded into the database, then we use that loaded schema to generate our JOOQ bindings.
That isn't possible today because of this line here:
https://github.com/etiennestuder/gradle-jooq-plugin/blob/master/src/main/groovy/nu/studer/gradle/jooq/JooqPlugin.groovy#L114
I've tried every way that I know to remove that dependency but I can't seem to remove that dependency once your plugin adds it.
We're having problem connect to oracle database using gradle-jooq-plugin
.
It still results in java.sql.SQLException: ORA-01017: invalid username/password; logon denied
Even if our password is correct.
We assume that problem might be with wrong encoding of special characters present in password like
ß ) $ %
jOOQ official style of generating resources is working well and without problems.
When I add
forcedTypes = [
{
userType = 'java.time.LocalDateTime'
converter = 'com.company.dao.LocalDateTimeConverter'
expression = '.*\\.DATE_TIME.*'
}
]
under
jooq {
main(sourceSets.main) {
generator {
database {
I get
java.lang.StackOverflowError
at nu.studer.gradle.util.Objects.hasCustomHashCode(Objects.java:179)
at nu.studer.gradle.util.Objects.deepHashCode(Objects.java:125)
at nu.studer.gradle.util.Objects$DeepHashCodeComparator.compare(Objects.java:215)
at nu.studer.gradle.util.Objects.sort(Objects.java:192)
at nu.studer.gradle.util.Objects.deepHashCode(Objects.java:104)
at nu.studer.gradle.util.Objects$DeepHashCodeComparator.compare(Objects.java:215)
at nu.studer.gradle.util.Objects.sort(Objects.java:192)
on both 1.0.5 and 2.0.2 versions
In my project, I want to have the generated jooq classes in a sub package. If I don't specify directory
, the generated classes are NOT put to src/main/java
(as documented). But if I specify src/main/java
, all my other packages and classes are removed from that folder. How can I forbid your plugin to delete the complete folder and just only delete all files under packageName
(which is in fact a folder in the file system)?
jooq {
myverydb(sourceSets.main) {
generator {
target {
packageName = 'my.very.own.package.db.jooq'
directory = 'src/main/java'
}
}
}
}
My package structure is like that (all in src/main/java
):
my.very.own.package.control
my.very.own.package.db.gateway
my.very.own.package.db.jooq
my.very.own.package.model
after jooq v-3.10.0,there is index attribute in genenate, the index attribute is not configurable at moment
I'm trying to generate database classes from an XML-File as described on the jooq website:
http://www.jooq.org/doc/3.8/manual/code-generation/codegen-xml/
Unfortunately I cannot get it to work. Here is my configuration attempt:
apply plugin: 'nu.studer.jooq'
jooq {
configuration(sourceSets.main) {
jdbc {
driver = 'org.jooq.util.xml.XMLDatabase'
properties {
property {
key = 'xml-file'
value = "../test.xml"
}
property {
key = 'dialect'
value = 'POSTGRES'
}
}
}
generator {
name = 'org.jooq.util.DefaultGenerator'
strategy {
name = 'org.jooq.util.DefaultGeneratorStrategy'
}
database {
name = 'org.jooq.util.postgres.PostgresDatabase'
inputSchema = 'cfg'
}
generate {
relations = true
deprecated = false
records = true
immutablePojos = true
fluentSetters = true
}
target {
packageName = 'de.db.gen.tst'
directory = "$projectDir/src/main/java"
}
}
}
}
Exception is:
java.lang.ClassNotFoundException: org.jooq.util.xml.XMLDatabase
Your help would be greatly appreciated!
build.gradle
buildscript {
ext {
jooqVersion = "3.8.4"
jooqPluginVersion = "2.0.6"
}
repositories {
mavenCentral()
jcenter()
maven {
url "https://plugins.gradle.org/m2/"
}
}
dependencies {
classpath("nu.studer:gradle-jooq-plugin:${jooqPluginVersion}")
}
configurations.classpath {
resolutionStrategy {
forcedModules = [
"org.jooq:jooq:${jooqVersion}",
"org.jooq:jooq-meta:${jooqVersion}",
"org.jooq:jooq-codegen:${jooqVersion}"
]
}
}
}
jooq {
version = "3.8.4"
edition = "OSS"
louise(sourceSets.main) {
generator {
name = 'org.jooq.util.DefaultGenerator'
database {
name = "org.jooq.util.jpa.JPADatabase"
properties {
property {
key = "packages"
value = "com.domain"
}
}
}
target {
packageName = "com.jooq"
directory = "src/generated/java"
}
}
}
}
Test.java (JPA Entity)
@Getter
@Entity
@Table(name = "test")
public class Test extends AbstractEntity<Long> {
private String name;
}
run
$ gradle generate
generate directory tree
.
└── java
└── com
└── jooq
├── DefaultCatalog.java
├── information_schema
│ ├── InformationSchema.java
│ ├── Keys.java
│ ├── Tables.java
│ └── tables
│ ├── Catalogs.java
│ ├── Collations.java
│ ├── ColumnPrivileges.java
│ ├── Columns.java
│ ├── Constants.java
│ ├── Constraints.java
│ ├── CrossReferences.java
│ ├── Domains.java
│ ├── FunctionAliases.java
│ ├── FunctionColumns.java
│ ├── Help.java
│ ├── InDoubt.java
│ ├── Indexes.java
│ ├── Locks.java
│ ├── QueryStatistics.java
│ ├── Rights.java
│ ├── Roles.java
│ ├── Schemata.java
│ ├── Sequences.java
│ ├── SessionState.java
│ ├── Sessions.java
│ ├── Settings.java
│ ├── TablePrivileges.java
│ ├── TableTypes.java
│ ├── Tables.java
│ ├── Triggers.java
│ ├── TypeInfo.java
│ ├── Users.java
│ ├── Views.java
│ ├── pojos
│ │ ├── Catalogs.java
│ │ ├── Collations.java
│ │ ├── ColumnPrivileges.java
│ │ ├── Columns.java
│ │ ├── Constants.java
│ │ ├── Constraints.java
│ │ ├── CrossReferences.java
│ │ ├── Domains.java
│ │ ├── FunctionAliases.java
│ │ ├── FunctionColumns.java
│ │ ├── Help.java
│ │ ├── InDoubt.java
│ │ ├── Indexes.java
│ │ ├── Locks.java
│ │ ├── QueryStatistics.java
│ │ ├── Rights.java
│ │ ├── Roles.java
│ │ ├── Schemata.java
│ │ ├── Sequences.java
│ │ ├── SessionState.java
│ │ ├── Sessions.java
│ │ ├── Settings.java
│ │ ├── TablePrivileges.java
│ │ ├── TableTypes.java
│ │ ├── Tables.java
│ │ ├── Triggers.java
│ │ ├── TypeInfo.java
│ │ ├── Users.java
│ │ └── Views.java
│ └── records
│ ├── CatalogsRecord.java
│ ├── CollationsRecord.java
│ ├── ColumnPrivilegesRecord.java
│ ├── ColumnsRecord.java
│ ├── ConstantsRecord.java
│ ├── ConstraintsRecord.java
│ ├── CrossReferencesRecord.java
│ ├── DomainsRecord.java
│ ├── FunctionAliasesRecord.java
│ ├── FunctionColumnsRecord.java
│ ├── HelpRecord.java
│ ├── InDoubtRecord.java
│ ├── IndexesRecord.java
│ ├── LocksRecord.java
│ ├── QueryStatisticsRecord.java
│ ├── RightsRecord.java
│ ├── RolesRecord.java
│ ├── SchemataRecord.java
│ ├── SequencesRecord.java
│ ├── SessionStateRecord.java
│ ├── SessionsRecord.java
│ ├── SettingsRecord.java
│ ├── TablePrivilegesRecord.java
│ ├── TableTypesRecord.java
│ ├── TablesRecord.java
│ ├── TriggersRecord.java
│ ├── TypeInfoRecord.java
│ ├── UsersRecord.java
│ └── ViewsRecord.java
└── public_
├── Public.java
why not generate Test.java Entity??
I tried to run the example from the README file, but even when just executing gradle
I get the error
$ gradle
FAILURE: Build failed with an exception.
* Where:
Build file '/home/moritz/workspace/foo/backend/build.gradle' line: 66
* What went wrong:
A problem occurred evaluating root project 'backend'.
> Cannot invoke method invoke() on null object
* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.
BUILD FAILED
Total time: 0.757 secs
It seems it doesn't like the sample(sourceSets.main)
line since sample
is not defined anywhere. I'm using Gradle 2.9 on Linux.
I have a similar issue to #4 - as far as the symptoms go. However, in my case it seems to go wrong whenever I use the com.android.library
plugin instead of the java
plugin.
My jOOQ configuration then fails to work with sourceSets.main
. How can I fix that?
My jOOQ configuration accounts(sourceSets.main)
fails with the following error:
$ ./gradlew generateAccountsJooqSchemaSource -i
[...]
FAILURE: Build failed with an exception.
* Where:
Build file '/home/maarten/projects/android-app/data/build.gradle' line: 46
* What went wrong:
A problem occurred evaluating project ':data'.
> Could not get unknown property 'main' for SourceSet container of type org.gradle.api.internal.tasks.DefaultSourceSetContainer.
Since any android module also has the option to configure android.sourceSets
, I also tried plugging that into my jOOQ configuration accounts(android.sourceSets.main)
$ ./gradlew generateAccountsJooqSchemaSource -i
[...]
FAILURE: Build failed with an exception.
* Where:
Build file '/home/maarten/projects/android-app/data/build.gradle' line: 46
* What went wrong:
A problem occurred evaluating project ':data'.
> Could not find method accounts() for arguments [source set main, build_d5novax2tyffqw6yv97530w4h$_run_closure5$_closure8@269966ac] on object of type nu.studer.gradle.jooq.JooqExtension.
Below is my gradle file. It declares an android library module, and it throws in flyway, followed by jOOQ code generation. I'm using jOOQ 3.6.4, since that was the latest one I could find that works well with Java 7
apply plugin: 'com.android.library'
apply plugin: 'org.flywaydb.flyway'
apply plugin: 'nu.studer.jooq'
buildscript {
dependencies {
classpath 'org.xerial:sqlite-jdbc:3.18.0'
classpath 'org.flywaydb:flyway-gradle-plugin:4.2.0'
classpath 'nu.studer:gradle-jooq-plugin:2.0.6'
}
}
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_7
targetCompatibility JavaVersion.VERSION_1_7
}
}
dependencies {
jooqRuntime 'org.xerial:sqlite-jdbc:3.18.0'
compile 'org.flywaydb:flyway-core:4.2.0'
compile 'org.jooq:jooq:3.6.4' // newest version compatible with Java 1.7
compile 'org.sqldroid:sqldroid:1.0.3'
testCompile 'junit:junit:4.12'
}
// Xerial SQLite does not create folders for DB files
task dbFolderCreate {
doLast {
new File("${projectDir}/build/tmp/").mkdirs()
}
}
flyway {
driver = 'org.sqlite.JDBC'
url = "jdbc:sqlite:${projectDir}/build/tmp/gradle.db"
locations = ["filesystem:${projectDir}/src/main/resources/sql/accounts"]
}
jooq {
version = '3.6.4'
edition = 'OSS'
accounts(sourceSets.main) { // this is line 46
jdbc {
driver = 'org.sqlite.JDBC'
url = "jdbc:sqlite:${projectDir}/build/tmp/gradle.db"
}
generator {
name = 'org.jooq.util.DefaultGenerator'
strategy {
name = 'org.jooq.util.DefaultGeneratorStrategy'
}
database {
name = 'org.jooq.util.sqlite.SQLiteDatabase'
excludes = 'schema_version' // flyway tables
}
generate {
deprecated = false
records = false
pojos = true
}
target {
packageName = 'com.abbink.androidapp.data.jooq'
directory = 'src/generated/java'
}
}
}
}
flywayMigrate.dependsOn dbFolderCreate
generateAccountsJooqSchemaSource.dependsOn flywayMigrate
test.dependsOn flywayClean
Implemented. Example usage:
generateSampleJooqSchemaSource {
def out = new ByteArrayOutputStream()
javaExecSpec = { JavaExecSpec s ->
s.standardOutput = out
s.errorOutput = out
s.ignoreExitValue = true
}
execResultHandler = { ExecResult r ->
if (r.exitValue != 0) {
throw new RuntimeException("jOOQ source code generation failed:\n\n" + out.toString())
}
}
}
The customType
section within customTypes
can have a type
option if we want the generated files to auto import that particular type. It's not mentioned in the documentation here: http://www.jooq.org/xsd/jooq-codegen-3.3.0.xsd so is possible to miss.
In a discussion with a user of the gradle-jooq-plugin, an interesting observation could be made. Apparently, the generated Tables.java
class, which holds convenience references to all the generated table literals, is not generated. This could be due to the gradle-jooq-plugin setting the wrong default values for jOOQ code generation configuration flags...?
The default in org.jooq.util.jaxb.Generate
is:
@XmlElement(defaultValue = "true")
protected Boolean globalTableReferences = true;
Could it be that this is false
by default?
target {
packageName = 'com.example.testabc.jooq'
directory = 'src/main/java'
}
deletes all content in "directory" without any notification or asking for confirmation.
I'd expect it to rebuild the innermost path including the package path. Therefore "jooq". If the user configures the project in such way he might lose important changes.
Having the following configuration:
................
target {
packageName = 'foo.bar.jooq.generated'
directory = 'src/main/java'
}
.................
task output as set by the plugin is set with the 'directory' variable only to 'src/main/java' instead of full package path: 'src/main/java/foo/bar/jooq/generated'.
The consequence is that rule generated clean<...> task clear all the project sources :)
I have an issue with defining matcher strategy when using nu.studer gradle plugin.
I have tried something like:
generator {
strategy {
matchers {
tables {
table {
pojoClass {
transform = 'PASCAL'
expression = '$0_POJO'
}
}
}
}
}
}
but when I try to run a build I get an error:
Execution failed for task ':generateSampleJooqSchemaSource'.
javax.xml.bind.MarshalException - with linked exception: [org.xml.sax.SAXParseException; lineNumber: 0; columnNumber: 0; cvc-complex-type.2.4.d: Invalid content was found starting with element 'matchers'. No child element is expected at this point.]
Keep in mind that when using .xml file to define matcher strategies like this:
<strategy>
<matchers>
<tables>
<table>
<pojoClass>
<transform>PASCAL</transform>
<expression>$0_POJO</expression>
</pojoClass>
</table>
</tables>
</matchers>
</strategy>
everything is fine.
Could someone please help and explain what am I doing wrong? Is the syntax for defining matcher rules inside gradle build different from what I have tried? As I can not find any examples for that - nor documentation regarding this.
Thanks a lot.
Best Regards, Marko
jOOQ XSD has been updated to 3.10.0, how to update jOOQ XSD version in plugin
plugins { id 'nu.studer.jooq' version '2.0.6' }
Running gradle clean build
removes "ALL" the source files in the corresponding source directory and not just the files in the designated generation package.
target { packageName = 'com.xx.xx.model' directory = 'src/main/gen' }
Since the package itself is provided, the clean task should only remove the generated files. Not the entire source folder.
how to use enum in gradle-jooq-plugin
I am trying to implement custom data binding (explained here) with gradle. My configuration looks like:
jooq {
version = '3.9.1'
edition = 'OSS'
database(sourceSets.main) {
jdbc {
driver = 'org.postgresql.Driver'
url = 'jdbc:postgresql://localhost:5432/test'
user = 'mert'
password = ''
}
generator {
name = 'org.jooq.util.DefaultGenerator'
database {
name = 'org.jooq.util.postgres.PostgresDatabase'
inputSchema = 'public'
includes = '.*'
excludes = 'SCHEMA_VERSION'
forcedTypes {
forcedType {
userType = 'com.google.gson.JsonElement'
binding = 'com.mert.test.PostgresJSONGsonBinding'
expression = '.*JSON.*'
types = '.*'
}
}
}
target {
packageName = 'com.mert.test.db'
directory = '/Users/mert/Projects/test/src/main/java'
}
}
}
}
The code generation is fine. But custom data binding is not happening. README's forcedType
example is different, and I am not sure I am doing the right thing. I went over the logs, but there isn't any warning or error regarding forcedType
or any sort.
I also tried with the following forcedType config, but again no custom binding is created:
forcedType {
name = 'com.mert.test.PostgresJSONGsonBinding'
expression = '.*JSON.*'
types = '.*'
}
This is using postgres jdbc 9.4.1212 and jooq plugin's v2.0.4.
The config of the code generation via DSL is mapped to a org.jooq.util.jaxb.Configuration instance, which is from the jOOQ version with which the gradle-jooq-plugin was built. This dependency should be cut by either mapping everything to a non-jOOQ object at config time, or by allowing the user to configure a jOOQ xml config file backed by the well-known jOOQ schema (or potentially both).
I'm writing my build using gradle-script-kotlin which allows you to write your build in kotlin which has infered typing.
Methods like this one don't play wel with a statically typed language:
https://github.com/etiennestuder/gradle-jooq-plugin/blob/master/src/main/groovy/nu/studer/gradle/jooq/JooqExtension.groovy#L45
Sometimes, when giving support to users of this plugin, I don't immediately notice that they're using this plugin, e.g. because there's no stack trace, log message, etc.
It would be useful if prior to calling GenerationTool
, an INFO level log message would be created with:
Ideally, you'd be using the org.jooq.tools.JooqLogger
for this, so this would log to the same place as the remaining logs.
How to keep the generated sources in Git repository and executing the task manually?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.