Maven build is picking different Jackson artefacts version on different hosts - java

I have multi-module projects, which has a multiple Jackson version, though in recently added module POM and Main Project POM it's 2.9.8 (included specifically).
and One of the modules has...
#JsonTypeInfo(
use = Id.NAME
)
#JsonSubTypes({#Type(TermQuery.class), #Type(AllMatchQuery.class)})
#JsonIgnoreProperties({"queryType"})
public abstract class Query implements Serializable {
.....
}
#JsonTypeName("term")
public class TermQuery extends Query {
}
at the time of serialization, I am getting this response(wrong) from a few of the hosts
Case-1
"queryType": "term"
while on the rest of the hosts I am getting result as expected
Case-2
"#type": "term"
At Case-1 expectation is annotated #type (as in case-2) while I am getting query type. Unable to pinpoint the issue, why it is happening?. though it seems Jackson version issue (I am not sure anymore now).
Other Info:-
Apache Maven 3.6.3
[INFO] \- com.xyz:jar:1.0.5-SNAPSHOT:compile (newly added module)
Any thought/way out to diagnose this issue would be appreciated?

Related

How to configure IntelliJ and hibernate-jpamodelgen annotations to launch test class from the IDE

We have a git multimodules projects MAVEN on IntelliJ. We use hibernate-jpamodelgen for criteria builder API.
We have web project using maven dependency entities library which are generating annotated class in entities => target folder.
When launching Install and test from mvn terminal it is working like a charm, but the issue is if we want to debug a test we have to launch with
-Dmaven.surefire.debug
option and with a remote application. It takes a time and not efficient. The problem is when we try to launch with right maven configuration (in IntelliJ) or directly in the class clicking the "play button" close to the method name it does not work, because it is creating in the web project all annotated classes but with empty body
for example what is in the dependency lib
#Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor", date = "2022-12-30T10:11:22.168+0400")
#SuppressWarnings({ "deprecation", "rawtypes" })
#StaticMetamodel(FixedAsset.class)
public abstract class FixedAsset_ extends com.seanergie.persistence.ObjectWithUnidAndVersion_ {
public static volatile SingularAttribute<FixedAsset, LocalDate> purchaseDate;
public static volatile SingularAttribute<FixedAsset, String> serialNumber;
public static volatile SingularAttribute<FixedAsset, MutableMoney> cost;
public static volatile SingularAttribute<FixedAsset, String> notes;
public static volatile SingularAttribute<FixedAsset, FixedAssetFilesStore> filesStore;
and what is created in other dependency target annotated class folder if i try to launch from intellij
#Generated(value = "org.hibernate.jpamodelgen.JPAMetaModelEntityProcessor", date = "2022-12-30T10:12:05.141+0400")
#SuppressWarnings({ "deprecation", "rawtypes" })
#StaticMetamodel(FixedAsset.class)
public abstract class FixedAsset_ extends com.seanergie.persistence.ObjectWithUnidAndVersion_ {
}
As you can see class is empty so compilation not work
We should be able to launch directly without creating a test configuration and modifying it (we have more than 100 test classes, so we can't create a conf for each one).
We see also that it try to compile all projects on each test
we tried to add in pom.xml
<dependency><!-- For launch tests directly from IntelliJ play button-->
<groupId>org.hibernate</groupId>
<artifactId>hibernate-jpamodelgen</artifactId>
<exclusions>
<exclusion>
<groupId>com.sun.activation</groupId>
<artifactId>jakarta.activation</artifactId>
</exclusion>
</exclusions>
<scope>provided</scope>
</dependency>
We also tried to deactivate or activate annotation processor in IntelliJ settings but nothing works
here in web project the hibernate mapping
<properties>
<mainClass>com.intranet.Main</mainClass>
<datasource.uri>jdbc:postgresql://localhost:5432/intranet?charSet=utf-8&amp;ApplicationName=${DATASOURCE_APPLICATION_NAME}</datasource.uri>
<datasource.pool_size.min>15</datasource.pool_size.min>
<datasource.pool_size.max>30</datasource.pool_size.max>
<hibernate.mapping.files>
<![CDATA[
<mapping-file>com/intranet-base.entities.xml</mapping-file>
<mapping-file>com/intranet-webapp.entities.xml</mapping-file>
<mapping-file>com/intranet-intranet.entities.xml</mapping-file>
<mapping-file>com/intranet-webapp.entities.xml</mapping-file>
<mapping-file>com/intranet2-intranet.entities.xml</mapping-file>
]]>
</hibernate.mapping.files>
<databaseInitializationHook.class>com.intranet.persistence.initialization.DatabaseInitializationHook</databaseInitializationHook.class>
<test.databaseInitializationHook.class>com.intranet.persistence.initialization.DatabaseInitializationHook</test.databaseInitializationHook.class>
</properties>
So finally when we launch mvn clean install even from IntelliJ (not only terminal) it create all annotated classes correctly in each library where we defined entities, but when we launch test it create another time same classes, but with empty body and in projects where entities are not defined (but use others as dependencies !)
What is the good way to make it work?
I do believe I have solved your puzzle.
The appearance of "empty" metamodel classes could be caused by one of the following:
some of plenty IDEA plugins influences on compile process and, obviously, fails
jpamodelgen annotation processor may perform extra work
And the last reason seems to be the actual one:
persistenceXml:
Per default the processor looks in /META-INF for persistence.xml. Specifying this option a persitence.xml file from a different location can be specified (has to be on the classpath)
ormXml:
Allows to specify additional entity mapping files. The specified value for this option is a comma separated string of mapping file names. Even when this option is specified /META-INF/orm.xml is implicit.
fullyAnnotationConfigured:
If set to true the processor will ignore orm.xml and persistence.xml.
I have checked and indeed placing META-INF/orm.xml with defined "foreign" entities into resources folder causes jpamodelgen to generate empty metamodel classes - as for me it looks like a bug.
You have following options (actually, depends on your project structure):
remove jpamodelgen from module dependencies if module does not define entity classes, also make sure dependency on jpamodelgen is defined as non-transitive, i.e. <scope>provided</scope>
rename extra xml mapping files - if you are on spring it is possible to specify those mappings via spring.jpa.mapping-resources
configure annotation processor as described in JBoss guide
UPD. based on #cyril comment.
First of all, defining dependencies (not imposing versions via <dependencyManagement>) in parent pom is a terrible idea - you have no chance to exclude such dependency in child modules, so, your parent pom is definitely broken.
However, I do believe you can meet your objectives (i.e. running tests via "green play button") even with broken parent pom - just follow JBoss guide and configure maven-compiler-plugin like:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgs>
<arg>-AfullyAnnotationConfigured=true</arg>
</compilerArgs>
</configuration>
</plugin>
IntelliJ does recognise such configuration.

Gradle project does not export implementation-dependency to other projects

My gradle project contains 3 sub-projects with one source file each:
root-project\
sub-project-abstract\
...AbstractFoo.java
sub-project-commons\
...ConcreteFoo.java (extends AbstractFoo)
sub-project-main\
...Main.java (instantiates ConcreteFoo)
build.gradle of sub-project-commons:
dependencies {
implementation(project(:sub-project-abstract))
}
build.gradle of sub-project-main:
dependencies {
implementation(project(:sub-project-commons))
}
The Main-class in sub-project-main is aware of ConcreteFoo, however, compilation fails with cannot access AbstractFoo.
For some reason, I expected sub-project-commons to "export" ConcreteFoo and AbstractFoo, since it's a implementation-dependency. Or in other words, form the perspective of sub-project-main, AbstractFoo is a transitive dependency.
However, this doesn't seem to be the case.
I know that I could probably make it work by explicitly adding sub-project-abstract as a direct dependency to sub-project-main. However, that's something I want to avoid due to the nature of the commons project (my actual project contains up to 10 subprojects, and it should be possible to reuse the commons-project without declaring a dependency to sub-project-abstract every single time the commons-project is referenced.
Is there a way to make the Main-class aware of AbstractFoo without directly declaring sub-project-abstract as a dependency (but indirectly via sub-project-commons)?
This is expected behavior for the implementation configuration. You should apply the Java Library Plugin and use the api configuration.
The key difference between the standard Java plugin and the Java Library plugin is that the latter introduces the concept of an API exposed to consumers. A library is a Java component meant to be consumed by other components. It’s a very common use case in multi-project builds [emphasis added], but also as soon as you have external dependencies.
The plugin exposes two configurations that can be used to declare dependencies: api and implementation. The api configuration should be used to declare dependencies which are exported by the library API, whereas the implementation configuration should be used to declare dependencies which are internal to the component.
[...]
Dependencies appearing in the api configurations will be transitively exposed to consumers of the library, and as such will appear on the compile classpath of consumers. Dependencies found in the implementation configuration will, on the other hand, not be exposed to consumers, and therefore not leak into the consumers' compile classpath. [...]
In sub-project-commons (Kotlin DSL):
plugins {
...
`java-library`
}
...
dependencies {
api(project(":sub-project-abstract"))
}
...

class file for org.springframework.data.repository.query.QueryByExampleExecutor not found

I am in the processing of upgrading spring-data-jpa and spring-data-commons dependencies.
Currently, ModuleA uses 1.8.0.RELEASE of data-jpa (which internally uses 1.10.0.RELEASE of jpa-commons.
ModuleB which has a dependency on ModuleA uses 1.9.4.RELEASE of data-jpa (which internally uses 1.11.4.RELEASE of jpa-commons).
I upgraded ModuleA to use 1.9.4 as well and everything still worked without any issues.
Now, when I upgrade ModuleB to pretty much anything above 1.9.x (say 1.10.0.RELEASE), I get the following error:
[FileName.Java] cannot access org.springframework.data.repository.query.QueryByExampleExecutor
class file for org.springframework.data.repository.query.QueryByExampleExecutor not found
I checked ModuleA (1.8.0 and 1.9.4) as well as ModuleB (1.9.4) and could not find a path to QueryByExampleExecutor, so why does it fail when I upgrade further? I did not find any explicit mention of QueryByExampleExecutor.
#Query annotation from import org.springframework.data.jpa.repository.Query is used, so it could be coming from that?
Any suggestions?

Processing Annotations Maven

I have a maven project and I want to create custom annotations to use in it.
I need that those annotations only be processed when some parameter is present, because I want to launch it a jenkins task.
How can I achieve it? Googling, I thought about creating a custom maven plugin for it, but I don't know how process the annotations in it.
This it is totally new for me and I would like your advice.
EDIT: I've tried creating a new maven plugin and with the reflections library find all classes with the annotation, but it isn't finding anything.
EDIT2: Following steps #Praveen Kumar, I was able to create a Custom Annotation Processor which process my method annotations. But I don't know how to execute the annotated method(I don't know either if this can be done)
#SupportedAnnotationTypes({"*"})
#SupportedSourceVersion(SourceVersion.RELEASE_8)
public class MyProcessor extends AbstractProcessor {
#Override
public boolean process(Set<? extends TypeElement annotations, RoundEnvironment roundEnv) {
for(Element el : roundEnv.getElementsAnnotatedWith(MyAnnotation.class)) {
// Execute annotated method???
}
}
}
PS. Sorry for my english.
Diego.
Solution to your question
Please use maven processor plugin for processing your custom annotations.
you can get maven processor plugin from this maven repository
Also, this example will help you a lot.
Once your maven is complete/perfect in all aspects, you can launch in Jenkins by setting your build goals.
Alternatively you can use mojo plugin to process/execute your custom annotations. please check this link if it of any help to you.

grails duplicate QuartzConfig

I use quartz in my grails project.
I now wanted to include the weceem plugin (that is a "lightweight" CMS)
It turns out that the plugin itself uses quatz as well.
Now I have a compile error saying:
Invalid duplicate class definition of class QuartzConfig :
The sources xxx\target\work\plugins\weceem-1.4\grails-app\conf\QuartzConfig.groovy and xxx\grails-app\conf\QuartzConfig.groovy each contain a class with the name QuartzConfig.
QuartzConfig.groovy /xxx/.link_to_grails_plugins/weceem-1.4/grails-app/conf
What can I do?
EDIT: Of cause, I want to use my QuartzConfig. It should override the plugin one

Categories