JOOQ 3.1 Code generate just for tables - java

Is it posible to run the code generator just for tables? I can exclude pkgs fine in <exclude> because they all end with _pkg but i am still generating functions and types as there is no common part in their name.

jOOQ 3.8 has added support for code generation flags to turn on/off specific types of generated artefacts (#3482). The configuration is:
<database>
<includePackages>false</includePackages>
<includeRoutines>false</includeRoutines>
...
Prior to version 3.8, you can still implement your own org.jooq.util.Database, e.g. overriding the OracleDatabase from jOOQ-meta, and then produce only TableDefinition items, none of the other items:
public class NoRoutinesOracleDatabase extends OracleDatabase {
#Override
protected List<RoutineDefinition> getRoutines0() {
return new ArrayList<>();
}
// other things you want to prevent...
}
You can then configure the code generator to use that Database:
<configuration>
<generator>
<database>
<name>com.example.NoRoutinesOracleDatabase</name>
...

Related

Jooq 3.9.3 deletes custom generated java files after generate

This is an issue we face with migration from jooq version 3.4.1 to 3.9.3.
We have a setup in which we extend JavaGenerator and override generatePojo(TableDefinition tableDefinition) to create some custom enum from data in database. This enum is created in a bit hackish way, using PrintWriterand writing the data into FooEnum.java file.
Something like this:
public class FooGenerator extends JavaGenerator {
#Override
protected void generatePojo(TableDefinition table) {
super.generatePojo(table);
// this works in jooq 3.4.1 but not in 3.9.3
generateEnumClasses(table); // loads data and produces FooEnum.java with PrintWriter
}
}
What happens is that the FooEnum.java gets generated and then deleted shortly afterwards. Funny enough, if i create Foo.txt file in the directory where enum should be created, this file survives clean install.
It seems that the enum is deleted after first (of two) generate goals:
jooq-codegen-maven:3.9.3:generate
Any ideas why is the enum getting deleted and how to keep the behavior from version 3.4.1 where it survives ?
This custom generator that we use to extend JavaGenerator is supplied to plugin with:
<groupId>org.jooq</groupId>
<artifactId>jooq-codegen-maven</artifactId>
<executions>
<execution>
<goals>
<goal>generate</goal>
</goals>
<id>some id</id>
<configuration>
<generator>
<name>org.jooq.util.FooGenerator</name>
// ...
</generator>
</configuration>
</execution>
</executions>
In case anybody else stumbles upon this, it seems that in newer jooq versions there is some cleanup code in
JavaGenerator {
public final void generate(Database db) {
// .... this deletes 'excess' java files
log.info("Removing excess files");
this.empty(this.getStrategy().getFileRoot(),this.scala?".scala":".java", this.files, this.directoriesNotForRemoval);
this.directoriesNotForRemoval.clear();
this.files.clear();
}
}
which deletes excess .java files.
Edit
Here is a link to github issue regarding this feature from Lukas comment.

Spring Soap web service client using a WSDL and codehaus jaxb2; need XmlRootElement?

I am working within an existing Spring web application; I need to write code to call to a SOAP web service that provides a WSDL. I also use Netbeans, though am willing to jump out to a command line whenever that's easier.
I have configured the Maven pom for the project to include the codehaus jaxb2-maven-plugin, and written a small test program to send a request. When that call is executed, I get an error saying that it cannot process one of the generated classes because it has no XmlRootElement annotation.
On searching further for that error, I find LOTS of requests for information on it, but none that apply. Most of them use a different JaxB library, and all of them give me examples of how to configure their plugin, not the one I have.
I suppose I can change plugins (I already have once), but what I would REALLY like is to find some decent documentation on THIS one. I need something that can be done on Java 7, not 8, that does not involve Spring 4 (or 5, or 6), preferably just an explanation of the various options that can be supplied to the maven plugin and/or the command line to generate classes so they can be marshalled and unmarshalled by Spring's default classes for the purposes.
--- Edit
Here's what I have at the moment; since it's testing code, I just have the marshaller declared and set up in the code instead of the configuration:
public class XClient extends WebServiceGatewaySupport {
public GetXResponse getXResponse(GetX XRequest) {
// do in configuration for production...
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setContextPath("com.X.pics.service");
setMarshaller(marshaller);
setUnmarshaller(marshaller);
String uri = "https://site.X.com/services/X";
WebServiceTemplate template = getWebServiceTemplate();
Object response = template.marshalSendAndReceive(uri,
XRequest
);
GetXResponse getXResponse = (GetXResponse) response;
return getXResponse;
}
}
When I run my program, it gives the following (just first lines):
org.springframework.oxm.MarshallingFailureException: JAXB marshalling exception; nested exception is javax.xml.bind.MarshalException
- with linked exception:
[com.sun.istack.internal.SAXException2: unable to marshal type "com.xo.pics.service.GetPricing" as an element because it is missing an #XmlRootElement annotation]
at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.reportError(XMLSerializer.java:237)
at com.sun.xml.internal.bind.v2.runtime.ClassBeanInfoImpl.serializeRoot(ClassBeanInfoImpl.java:322)
at com.sun.xml.internal.bind.v2.runtime.XMLSerializer.childAsRoot(XMLSerializer.java:483)
I put in the line about preferring Spring libraries since a lot of answers on SO seem to take the form of "Change over to this tool/library", not because I didn't think it could be done in Spring. I'll be happy to configure and use a marshaller within Spring, as soon as I figure out (or am told) how.
I finally got this working; it does seem like it ought to be easier.
The POM file entry for the JAXB Maven plugin now looks like this:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxb2-maven-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<sourceType>wsdl</sourceType>
<sources>
<source>C:/projects/gw/src/main/resources/wsdl/xo2.wsdl</source>
</sources>
<extension>true</extension>
<xjbSources>
<xjbSource>bindings.xjb</xjbSource>
</xjbSources>
</configuration>
</plugin>
One of the difficulties I faced was a lack of documentation on the options here; I eventually looked inside the jar file in the plugin code and found the jaxb2-maven-plugin.pom there, and looked through the unformatted documentation for the various options. This is how I discovered the "sourceType", "sources", and "xjbSources" tags. It was also looking in that part of my .m2 directory that helped me realize the different versions available, and the docs available on the web do warn you of the major differences between 1.x and 2.x.
Anyway, I had found the following bindings file, though wasn't sure until later how to specify a bindings file in this version of the plugin:
<?xml version="1.0"?>
<jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb"
xmlns:xjc= "http://java.sun.com/xml/ns/jaxb/xjc"
jxb:extensionBindingPrefixes="xjc" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<jxb:bindings>
<jxb:globalBindings>
<xjc:simple/>
</jxb:globalBindings>
</jxb:bindings>
</jxb:bindings>
The specification of in the bindings is what causes the #XmlRootElement in the generated sources; you need this if your WSDL has complex types that have a defined name.
Then my client boiled down to this:
public class XOClient extends WebServiceGatewaySupport {
public GetPricingResponse getPricingResponse(GetPricing pricingRequest) {
Jaxb2Marshaller marshaller = new Jaxb2Marshaller();
marshaller.setClassesToBeBound(GetPricing.class, GetPricingResponse.class);
setMarshaller(marshaller);
setUnmarshaller(marshaller);
String uri = "https://blah.blah.blah.com/services/pricing";
Object o = getWebServiceTemplate().marshalSendAndReceive(uri, pricingRequest);
GetPricingResponse response = (GetPricingResponse)o;
return response;
}
}
In the final Spring application, I would be more likely to configure the marshaller URI and bound classes instead of writing code to set them, but to use in my little testing program this was easier.
So this allows me to build up my pricingRequest object and get back a GetPricingResponse object, and use any of the other API methods similarly.
Hope this is a help to someone else.

SonarQube: Custom Java Rules Not Visible in UI

I've been trying for quite some time to implement my own custom Java rule(s) on SonarQube. However, it seems like no matter what I try, I can't get the new rule to show up on the SonarQube UI.
I only have one rule at the moment, a security rule that checks to see if text output is sanitized. The rule extends BaseTreeVisitor and implements JavaFileScanner. It overrides visitMethodInvocation to do some checks on String arguments for the relevant methods. Here is the rule definition annotation:
#Rule(key = "Sanitize_HTML",
name = "HTML Responses Should be Sanitized",
tags = {"security", "owasp-a3"},
priority = Priority.CRITICAL)
#ActivatedByDefault
#SqaleSubCharacteristic(RulesDefinition.SubCharacteristics.SECURITY_FEATURES)
#SqaleConstantRemediation("10min")
public class SanitizeHTMLCheck extends BaseTreeVisitor implements JavaFileScanner{...}
After writing the rule, I wanted to test it, but quickly realized I had to wrap it in a plugin in order to do so. I wrote three additional classes for this, based entirely on the provided example plugin. Here's the base class:
public class SecurityPlugin extends SonarPlugin{
public List getExtensions(){
return Arrays.asList(
JavaClasspath.class,
JavaTestClasspath.class,
Java.class,
SecurityRulesDefinition.class,
SonarComponents.class,
DefaultJavaResourceLocator.class);
}
}
The classes in the list are all irrelevant (added in desperation) except for SecurityRulesDefinition. It mirrors the structure of the MyJavaRulesDefinition class from the example:
public class SecurityRulesDefinition implements RulesDefinition{
public void define(Context context){
NewRepository repository = context
.createRepository(RulesList.REPOSITORY_KEY, Java.KEY)
.setName("Security Rules");
AnnotationBasedRulesDefinition.load(repository, Java.KEY, RulesList.getChecks());
for(NewRule rule : repository.rules()){
rule.setInternalKey(rule.key());
}
repository.done();
}
}
Finally, just like the example, here's RulesList, where all of my rule classes are supposed to go:
public class RulesList {
public static final String REPOSITORY_KEY = "security_java";
private RulesList(){}
public static List<Class> getChecks(){
return ImmutableList.<Class>builder().addAll(getJavaChecks()).addAll(getJavaTestChecks()).build();
}
//Add all checks to here...
public static List<Class<? extends JavaCheck>> getJavaChecks(){
return ImmutableList.<Class<? extends JavaCheck>>builder()
.add(SanitizeHTMLCheck.class)
.build();
}
//Put all test checks here
public static List<Class<? extends JavaCheck>> getJavaTestChecks(){
return ImmutableList.<Class<? extends JavaCheck>>builder()
.build();
}
}
Like I said, these are all pretty much ripped from the example plugin, so I have no idea what could be wrong with them.
I'm using Eclipse with M2E to try and build the plugin. As suggested by the documentation's Coding A Plugin page, I've added the following plugin tag to my POM.xml:
<build>
<plugins>
<plugin>
<groupId>org.codehaus.sonar</groupId>
<artifactId>sonar-packaging-maven-plugin</artifactId>
<version>1.13</version>
<extensions>true</extensions>
<configuration>
<pluginKey>securityrules</pluginKey>
<pluginClass>org.myOrg.sonar_analysis.security_rules_java.SecurityPlugin</pluginClass>
<pluginName>Sonar Java Custom Security Rules</pluginName>
<pluginDescription>Implements several checks against OWASP-Top-10 vulnerabilities.</pluginDescription>
</configuration>
</plugin>
</plugins>
</build>
Now, according to everything I've read, I should be able to build the project (right-click on the project > Run As > Maven Build (with goal "package") and drop the resulting .jar into SONAR_HOME/extensions/plugins, and when I restart the server, the rule (and repository) should be there. However, no matter what I try, it's never there. I've spent hours combing the internet and trying anything I find, but the rule never shows up in the UI.
Am I missing something? Have I done something wrong? Is my code incorrect or missing anything?
Thank you for reading this monster post. Any advice you have is valuable, as I'm out of ideas.
The structure of the code seems right for me (more or less).
In the SecurityPlugin class, you return many classes (JavaClasspath.class, JavaTestClasspath.class and so on)... What are they for? What do they implement/extend?
In my expirience you need to return there:
- a "RulesDefinition" (to see the rule in SonarQube) and
- a CheckRegistrar (to let the checks being used).
Maybe my small rules project will give you some ideas (https://github.com/arxes-tolina/sonar-plugins ; one rule with two checks).
If you are still struggling with the rules try to set the sonar.log.level-property (./conf/sonar.properties) to DEBUG and watch the start-up of SonarQube.

How to tell checker that a legacy method will accept Nullable types?

Consider this:
#Nullable Object obj = null;
Optional<Object> optional = Optional.ofNullable(obj);
This fails because checker-framework assumes ofNullable cannot accept null values (after all, its parameter is not marked as #Nullable).
Is there a good way to tell checker-framework that this method (or other methods in legacy code that I cannot change), accepts #Nullable types everywhere without having to change code everywhere?
EDIT: this answer was based on #mernst help in the comments and in the Checker Framework's Issue tracker
If you, like me, do not want or cannot use the annotated JDK, you will run into this issue.
Note: In most Java shops I've worked, we simply cannot switch which compiler we use or provide a "custom" JDK (that's really unthinkable). For that to be portable, I would have to add the custom JDK to my source repository, for starters, or distribute it to every machine, including CI servers, where the code compiles, and make sure they are in the exact same path across different OS's. Just not cool.
The solution is to provide stub classes and pass them as an argument to the javac process.
This can be done quite easily with whatever tool you use to compile.
For example, with Maven (using the standard compiler plugin):
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessors>
<annotationProcessor>org.checkerframework.checker.nullness.NullnessChecker</annotationProcessor>
</annotationProcessors>
<compilerArgs>
<arg>-Astubs=checkerframework/stubs</arg>
<arg>-AstubWarnIfNotFound</arg>
</compilerArgs>
</configuration>
</plugin>
You also need to add these dependencies to your project:
<dependency>
<groupId>org.checkerframework</groupId>
<artifactId>checker-qual</artifactId>
<version>1.9.2</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.checkerframework</groupId>
<artifactId>checker</artifactId>
<version>1.9.2</version>
<optional>true</optional>
</dependency>
Here, checkerframework/stubs is a directory (relative to the location of the pom), containing the stubs. For Optional, my stub looks like this (strangely, stubs must be named *.astub, so this file is called Optional.astub):
package java.util;
import org.checkerframework.checker.interning.qual.*;
import javax.annotation.Nullable;
class Optional<T> {
static <T> Optional<T> ofNullable(#Nullable T value);
#Nullable T orElse(#Nullable T other);
}
This approach is simple, requires little work, does not mess with which compiler I use or the Java libraries at all, makes sure these definitions are only used with the checkerframework (so I can, for example, add this to a Maven profile and enable it only if I want to by simply passing a Maven argument), will work across machines and OS's without previous setup in the true Java way of doing things.
I'm not sure why you say "its parameter is not marked as #Nullable".
When I look at file
checker-framework/checker/jdk/nullness/src/java/util/Optional.java,
I see the following annotated method:
public static <T> Optional<#NonNull T> ofNullable(#Nullable T value) {
return value == null ? empty() : of(value);
}
Furthermore, when I run the Checker Framework on the following code, it issues no warning.
// run like this:
// javacheck -g TestOptional.java -processor nullness
import java.util.*;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.checkerframework.checker.nullness.qual.NonNull;
public class TestOptional {
void m() {
#Nullable Object obj = null;
Optional<Object> optional1 = Optional.ofNullable(obj);
}
}
I'm not sure what is going on in your case because you didn't provide a complete test case, you didn't say what command you ran, and you didn't give an actual error message. (You did provide a diagnosis, but I'm not sure it is accurate.)
Maybe providing more details would enable better understanding of your problem.

Using a compile-time environment variable to configure RestApplicationPath

As stated in the documentation of rest-dispatch, the rest application path must be configured in the GIN module via a constant, here "/api/v1":
public class DispatchModule extends AbstractGinModule {
#Override
protected void configure() {
RestDispatchAsyncModule.Builder dispatchBuilder =
new RestDispatchAsyncModule.Builder();
install(dispatchBuilder.build());
bindConstant().annotatedWith(RestApplicationPath.class).to("/api/v1");
}
}
I would like to make the "/api/v1" constant be resolved at compile time, based on an environment variable set by the build system depending on the target environment (prod, dev, etc...), and on other criteria (the build artifact major version...).
The problem is I do not manage to rely on a compile time variable.
Neither TextResource/CssResource nor GWT's deferred binding won't help here, since GWT.create() cannot be used in GIN module. Another option I considered is using a custom Generator, but this seems to be too complex for this very simple need.
How do you solve this problem ?
If you use Maven as your build system, you could leverage the templating-maven-plugin to generate a Java class that will contain static variables defined in your POM file. That generated class will be used by your GWT code.
For example, you would want to populate a BuildConstants class template
public class BuildConstants {
// will be replaced by Maven
public static final String API_VERSION = "${myapi.version}";
}
and using a Maven property:
<myapi.version>v1</myapi.version>
that will be compiled to
public class BuildConstants {
// will be replaced by Maven
public static final String API_VERSION = "v1";
}
and you could reference those constants from within your DispatchModule:
bindConstant().annotatedWith(RestApplicationPath.class).to("/api/" + BuildConstants.API_VERSION);
Here's a sample config of the templating-maven-plugin that I use in a project:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>templating-maven-plugin</artifactId>
<version>1.0-alpha-3</version>
<executions>
<execution>
<id>filter-src</id>
<goals>
<goal>filter-sources</goal>
</goals>
<configuration>
<sourceDirectory>${basedir}/src/main/java-templates</sourceDirectory>
<outputDirectory>${project.build.directory}/generated-sources/java-templates
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
There's no reason you couldn't replace the bindConstant() with a #Provides method (or other bind().toProvider(), which would let you use a TextResource and/or deferred-binding, or whatever.
Asn an example (untested though), the code below uses JSNI to read the value from the host page, which makes it runtime dependent (rather than compile-time):
#Provides #RestApplicationPath native String provideRestApplicationPath() /*-{
return $wnd.restApplicationPath;
}-*/;
Following Thomas Broyer suggestion and Simon-Pierre, you could even bind different root .gwt.xml files depending on your maven profile. Then you choose the appropriate Gin module class where your constants are bound.
That is what we do inside the CarStore companion project of GWTP do do Form factors for example.

Categories

Resources