Alfresco 3.2c has a tracking image that's injected into the page footer using Javascript that I need to remove for a project. The javascript is actually hard coded in the SDK in the alfresco-share-src.zip in the class org/alfresco/web/scripts/MessagesWebScript.java.
We're currently building Alfresco using a Maven project and it pulls most of Alfresco and Share from maven plugins and repositories, giving us a clean root build additions in. However since this class is hard coded and we don't want to touch the original jars/zips, I thought I could just add a new copy of the file to share/src/main/java/org/alfresco/web/scripts/MessagesWebScript.java, compiling it into the war file's WEB-INF and thereby overriding what would get loaded from the jar (yes, I know a bad way of doing it).
However, if I just add the file, I get the error /share/src/main/java/org/alfresco/web/scripts/MessagesWebScript.java:[48,80] error: cannot find symbol on the line
public class MessagesWebScript extends org.springframework.extensions.webscripts.MessagesWebScript
Which leads me to believe it's not pulling in the same dependencies used to build the war file (namely the spring-surf-parent dependency). If I try to add that dependency to the share.pom file (shown below), maven successfully builds, but the dependency somehow pulls in the servlet API jar files, adds them to the war and then I get the expected The method getJspApplicationContext(ServletContext) is undefined for the type JspFactory errors.
<dependency>
<groupId>org.springframework.extensions.surf</groupId>
<artifactId>spring-surf-parent</artifactId>
<version>1.2.0-M3</version>
</dependency>
My share.pom looks like the following:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>share</artifactId>
<name>Alfresco Share Client</name>
<packaging>war</packaging>
<description>Alfresco Share Client</description>
<parent>
<groupId>nz.net.mycompany</groupId>
<artifactId>custom-alfresco</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<dependencies>
<dependency>
<groupId>${alfresco.groupId}</groupId>
<artifactId>share</artifactId>
<type>war</type>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.1</version><!--$NO-MVN-MAN-VER$-->
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.2.5</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.github.searls</groupId>
<artifactId>jasmine-maven-plugin</artifactId>
<version>1.3.1.2</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
<resource>
<directory>jetty</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>exec</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>${basedir}/src/scripts/less2css.sh</executable>
<arguments>
<argument>${basedir}</argument>
</arguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<excludes>
<!-- Integration Tests should not be run here -->
<exclude>**/IT*.java</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.14.1</version>
<executions>
<execution>
<goals>
<!-- <goal>integration-test</goal> -->
<!-- <goal>verify</goal> -->
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>com.github.searls</groupId>
<artifactId>jasmine-maven-plugin</artifactId>
<version>1.3.1.2</version>
<executions>
<execution>
<goals>
<goal>test</goal>
</goals>
</execution>
</executions>
<configuration>
<webDriverClassName>org.openqa.selenium.phantomjs.PhantomJSDriver</webDriverClassName>
<webDriverCapabilities>
<phantomjs.binary.path>${project.basedir}/src/test/bin/phantomjs</phantomjs.binary.path>
</webDriverCapabilities>
<preloadSources>
<source>${project.basedir}/src/test/javascript/fixtures/fixture_messages.js</source>
</preloadSources>
<jsSrcDir>${project.basedir}/target/share/js/</jsSrcDir>
<jsTestSrcDir>${project.basedir}/src/test/javascript/</jsTestSrcDir>
<sourceIncludes>
<!-- add the ones we want first -->
<include>**/yui-common.js</include>
<include>**/alfresco.js</include>
<!-- Then the default -->
<include>**/*.js</include>
</sourceIncludes>
<haltOnFailure>false</haltOnFailure>
</configuration>
</plugin>
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<!-- Here is can control the order of overlay of your (WAR, AMP, etc.) dependencies
| NOTE: At least one WAR dependency must be uncompressed first
| NOTE: In order to have a dependency effectively added to the WAR you need to
| explicitly mention it in the overlay section.
| NOTE: First-win resource strategy is used by the WAR plugin
-->
<overlays>
<!-- The current project customizations -->
<overlay />
<!-- The Share WAR -->
<overlay>
<groupId>${alfresco.groupId}</groupId>
<artifactId>share</artifactId>
<type>war</type>
<!-- To allow inclusion of META-INF -->
<excludes />
</overlay>
</overlays>
</configuration>
</plugin>
</plugins>
</build>
</project>
If I understand correctly, you want to override a single Java class, which in this case, happens to implement a web script, but your solution of repackaging the share WAR with a forked copy of this class is not working.
Re-defining core Alfresco (or Share in this case) classes is a bad idea. This web script is declared in the Spring config file alfresco/slingshot-application-context.xml in the webapp classpath, and therefore what you should be doing is overriding it in your own *-context.xml file under alfresco/web-extension, e.g.
<?xml version='1.0' encoding='UTF-8'?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<!-- I18N resources and messages Web Script -->
<bean id="webscript.org.springframework.extensions.messages.get"
parent="webscript"
class="my.custom.namespace.MessagesWebScript">
<property name="webFrameworkConfigElement" ref="webframework.config.element"/>
<property name="dependencyHandler" ref="dependency.handler"/>
</bean>
</beans>
There is no reason why you should not implement the override through Spring from the start. Spring beans are designed for this purpose and it adds very little to the effort while giving you the ability to more effectively debug if it does not work as you expect.
Obviously you will also need to make sure that your custom class my.custom.namespace.MessagesWebScript compiles as part of your build, and it sounds like it is not doing so at present. This is probably because you are missing some JAR (not WAR) dependencies in your POM - take a look at the Google Docs integration Share POM for the set which we use.
Lastly I would suggest that your package your customisation as an AMP file. The Alfresco Maven SDK provides full support for this and you just need to declare it as a parent - see the Google Docs parent POM for an example.
Related
I have an App Engine project. Here is a sample repo, but it only contains a few files:
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.happycoding</groupId>
<artifactId>google-cloud-hello-world</artifactId>
<version>1</version>
<packaging>war</packaging>
<properties>
<!-- App Engine currently supports Java 8 -->
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.google.appengine</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>1.9.71</version>
</plugin>
</plugins>
</build>
</project>
appengine-web.xml
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
<application>MY_PROJECT_ID_HERE</application>
<version>1</version>
<threadsafe>false</threadsafe>
<sessions-enabled>true</sessions-enabled>
<runtime>java8</runtime>
</appengine-web-app>
HelloWorldServlet.java
package io.happycoding.servlets;
import java.io.IOException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#WebServlet("/hello")
public class HelloWorldServlet extends HttpServlet {
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html;");
response.getOutputStream().println("<h1>Hello world!</h1>");
}
}
I do not have a web.xml file because I'm using the #WebServlet annotation instead. This has worked perfectly for years.
The only problem was that I was restricted to using Java 8, so I was happy to see App Engine announce support for Java 11. I am now trying to upgrade my App Engine project to Java 11.
I started by changing the appengine-web.xml file to contain this line:
<runtime>java11</runtime>
I also changed the pom.xml file:
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
I run mvn appengine:devserver (which works fine before this change), and I get this error:
ClassLoader is jdk.internal.loader.ClassLoaders$AppClassLoader#78308db1, not a URLClassLoader.
I gather that this is because the App Engine Maven plugin itself requires Java 8. I also learn that the App Engine Maven plugin is deprecated, and that I should upgrade to the Cloud SDK Maven plugin. Okay fine.
I follow this guide and I change the plugin in my pom.xml file to this:
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>2.2.0</version>
</plugin>
I then run mvn package appengine:run (because of course the command to run a devserver changed too), but now I get this error:
java.io.FileNotFoundException: /home/kevin/gcloud-tutorials/hello-world/target/hello-world-1/WEB-INF/web.xml (No such file or directory)
The error says it can't find a web.xml file, but I shouldn't need one because I'm using the #WebServlet annotation! My pom.xml file also contains a <failOnMissingWebXml>false</failOnMissingWebXml> property, but I don't know whether that does anything with the new plugin.
Am I missing a step or property? How do I upgrade my App Engine project to use Java 11, without also requiring a web.xml file?
There are some pretty huge differences between App Engine's Java 8 runtime and its Java 11 runtime.
Specifically, the Java 8 runtime included a Jetty web server that automatically ran your code, but the Java 11 runtime no longer includes this, so you have to include it yourself.
There is a migration guide here but I found that very confusing to follow, so I'll try to outline the steps here:
Step 1: Migrate from appengine-web.xml to app.yaml.
Delete your appengine-web.xml file, and create a new app.yaml file. My app.yaml file only contained a single line:
runtime: java11
Step 2: Add a main entry point class that runs a web server.
There are many ways to do this, but there's what I did:
package io.happycoding;
import java.net.URL;
import org.eclipse.jetty.annotations.AnnotationConfiguration;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.webapp.Configuration;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.webapp.WebInfConfiguration;
/**
* Starts up the server, including a DefaultServlet that handles static files,
* and any servlet classes annotated with the #WebServlet annotation.
*/
public class ServerMain {
public static void main(String[] args) throws Exception {
// Create a server that listens on port 8080.
Server server = new Server(8080);
WebAppContext webAppContext = new WebAppContext();
server.setHandler(webAppContext);
// Load static content from inside the jar file.
URL webAppDir =
ServerMain.class.getClassLoader().getResource("META-INF/resources");
webAppContext.setResourceBase(webAppDir.toURI().toString());
// Enable annotations so the server sees classes annotated with #WebServlet.
webAppContext.setConfigurations(new Configuration[]{
new AnnotationConfiguration(),
new WebInfConfiguration(),
});
// Look for annotations in the classes directory (dev server) and in the
// jar file (live server)
webAppContext.setAttribute(
"org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern",
".*/target/classes/|.*\\.jar");
// Handle static resources, e.g. html files.
webAppContext.addServlet(DefaultServlet.class, "/");
// Start the server! 🚀
server.start();
System.out.println("Server started!");
// Keep the main thread alive while the server is running.
server.join();
}
}
This class uses Jetty to run a web server, and then adds the rest of your code to that web server. This code assumes that everything will be packaged in the same .jar file.
Step 3: Modify pom.xml
Your pom.xml needs a few things:
Dependencies for the web server you're running. I used Jetty.
Plugins for packaging your code. I chose to package mine as a single uber jar, so I used maven-resources-plugin and maven-shade-plugin.
Plugins for running your code locally. The old appengine-maven-plugin does not work for deploying locally, because it still requires appengine-web.xml for some reason. Because I chose the uber jar approach, I used exec-maven-plugin.
The appengine-maven-plugin does still work for deploying to the live server, so you still need it for that.
If that sounds confusing, you're right. But putting it all together, here's what I came up with:
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.happycoding</groupId>
<artifactId>app-engine-hello-world</artifactId>
<version>1</version>
<properties>
<!-- App Engine currently supports Java 11 -->
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<jetty.version>9.4.31.v20200723</jetty.version>
<!-- Project-specific properties -->
<mainClass>io.happycoding.ServerMain</mainClass>
<googleCloudProjectId>YOUR_PROJECT_ID_HERE</googleCloudProjectId>
</properties>
<dependencies>
<!-- Java Servlets API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
<!-- Jetty -->
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-annotations</artifactId>
<version>${jetty.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Copy static resources like html files into the output jar file. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<executions>
<execution>
<id>copy-web-resources</id>
<phase>compile</phase>
<goals><goal>copy-resources</goal></goals>
<configuration>
<outputDirectory>
${project.build.directory}/classes/META-INF/resources
</outputDirectory>
<resources>
<resource><directory>./src/main/webapp</directory></resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
<!-- Package everything into a single executable jar file. -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals><goal>shade</goal></goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>${mainClass}</mainClass>
</transformer>
</transformers>
</configuration>
</execution>
</executions>
</plugin>
<!-- Exec plugin for deploying the local server. -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<goals>
<goal>java</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>${mainClass}</mainClass>
</configuration>
</plugin>
<!-- App Engine plugin for deploying to the live site. -->
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>appengine-maven-plugin</artifactId>
<version>2.2.0</version>
<configuration>
<projectId>${googleCloudProjectId}</projectId>
<version>1</version>
</configuration>
</plugin>
</plugins>
</build>
</project>
I put all of this into an example project available here.
I am using the google BETA API: AutoML Natural Language, after training the API, I did tests in a Java SE project obtaining a satisfactory result, however, when I migrated it to a Java EE project I got different problems. About:
-Java -version: 1.8.0_201
-Payara Version: 5.191
-google-cloud-automl dependecy: 0.97.0-beta
When I try to run the entity extraction service (PredictionServiceClient class) it returns the error java.lang.NoSuchMethodError: com.google.common.base.Preconditions.checkArgument (ZLjava / lang / String; CLjava / lang / Object;) V, according to different sources this error is caused by conflicts between different versions of the guava library. I think my particular error is caused because guava's version is 19.0.0 in payara and google-cloud-automl requires a version > 20.
To solve this error payara suggests here modifying the file glassfish-application.xml, "With this, the libraries included in the EAR's lib / directory will take precedence", however this did not work for me.
The code was written with the help of this documentation
glassfish-application.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE glassfish-application PUBLIC "-//GlassFish.org//DTD GlassFish Application Server 3.1 Java EE Application 6.0//EN" "http://glassfish.org/dtds/glassfish-application_6_0-1.dtd">
<glassfish-application>
<classloading-delegate>false</classloading-delegate>
</glassfish-application>
pom[EJB].xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>AutoMLTest</artifactId>
<groupId>co.com.group.automl</groupId>
<version>1.0</version>
</parent>
<groupId>co.com.group.automl</groupId>
<artifactId>AutoMLTest-ejb</artifactId>
<version>1.0</version>
<packaging>ejb</packaging>
<name>AutoMLTest-ejb</name>
<properties>
<endorsed.dir>${project.build.directory}/endorsed</endorsed.dir>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.google.cloud</groupId>
<artifactId>google-cloud-automl</artifactId>
<version>0.97.0-beta</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<targetPath>META-INF</targetPath>
<directory>src</directory>
<includes>
<include>jax-ws-catalog.xml</include>
<include>wsdl/**</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
<plugins>
<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>
<compilerArguments>
<endorseddirs>${endorsed.dir}</endorseddirs>
</compilerArguments>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-ejb-plugin</artifactId>
<version>2.3</version>
<configuration>
<ejbVersion>3.1</ejbVersion>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.6</version>
<executions>
<execution>
<phase>validate</phase>
<goals>
<goal>copy</goal>
</goals>
<configuration>
<outputDirectory>${endorsed.dir}</outputDirectory>
<silent>true</silent>
<artifactItems>
<artifactItem>
<groupId>javax</groupId>
<artifactId>javaee-endorsed-api</artifactId>
<version>7.0</version>
<type>jar</type>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Method AutoML Extraction.xml
public void extracNL(String content) throws Exception {
String googleCredentials = "/path/credentials.json"
GoogleCredentials credentials = GoogleCredentials.fromStream(new FileInputStream(googleCredentials)).createScoped(Lists.newArrayList("https://www.googleapis.com/auth/cloud-platform"));
PredictionServiceSettings settings =
PredictionServiceSettings.newBuilder().setCredentialsProvider(FixedCredentialsProvider.create(credentials)).build();
//The problem is presented in this line of code
PredictionServiceClient serviceClient =
PredictionServiceClient.create(settings);
ModelName modelName = ModelName.of("projectId", "computeRegion", "modelId");
TextSnippet snippet = TextSnippet.newBuilder().setContent(content).setMimeType("text/plain").build();
ExamplePayload payload = ExamplePayload.newBuilder().setTextSnippet(snippet).build();
Map<String, String> params = new HashMap<>();
PredictResponse response = serviceClient.predict(modelName, payload, params);
List<PredictGoogleDTO> predictionsTmp = new ArrayList<>();
for (AnnotationPayload annotationPayload : response.getPayloadList()) {
if (annotationPayload.getDisplayName().equals("Person")) {
System.out.println("DisplayName="+annotationPayload.getDisplayName());
System.out.println("Content="+annotationPayload.getTextExtraction().getTextSegment().getContent());
}
}
}
Is there another way to do this? is it really impossible for my application to use the guava version in the pom and not the payara server? after testing the command line in maven mvn dependecy; tree -Dverbose in the path of my project I do not get any dependencies error. can then guava be the cause of this error really? I feel that I have tried everything and I can not find a possible solution to my problem, in advance thank you.
probably many of them will be presented with this and other errors when using the AutoML Natural Language API in their BETA version, this is normal and we must assume that as a BETA version this type of problem will be present. My solution was to isolate the consumption of the API from my JAVA EE application, implementing for the first time a lambda function in AWS (Amazon Web Service) and consuming the service through a REST call to this function. This worked perfect for me, and it is a clean solution (from my perspective). Regards.
We are using a setup with Spring Boot, Hibernate, Query DSL and Maven with Java 1.8
Recently, I've added Query DSL to the project with the configuration listed below. To make it work, I had to configure the Java Compiler in the eclipse project settings to allow Annotation Processing and also add the Query DSL .jar file to the eclipse Annotation Factory Path.
This setup worked as expected. It generated the custom Q classes and I could use them in my code. When now running the mvn clean install on the command line, every class in my code throws the error cannot find symbol, because the class is missing. Is there anything else I need to configure - similar to the .jar file in the eclipse settings - to make the build process work?
EDIT: This question is not a duplicate of this question because I did not ask why this error (cannot find a symbol) occurs but rather how to configure QueryDSL to also work on the command line.
EDIT2: I have now tried to integrate the build-helper-maven-plugin to use multiple source paths as an input. This did not help either. I also tried to generate the files into a src folder. It did not help either.
When I first compile the library in eclipse, the mvn compile goes through on the command line, but mvn clean compile still fails, because it just uses the compiled files of eclipse again. The apt-maven-plugin is executed, which can be seen just before the build process fails:
[INFO] --- apt-maven-plugin:1.1.3:process (default) # project1 ---
[INFO]
[INFO] --- build-helper-maven-plugin:1.9.1:add-source (add-source) # project1 ---
[INFO] Source directory: C:\Users\user1\git\project1\src\main\generated added.
[INFO]
[INFO] --- maven-processor-plugin:2.2.4:process (process) # project1 ---
[ERROR] diagnostic: [...]
EDIT3: When I remove every import statement which is referring to the Q classes, the build process goes through (obviously). It is, however, remarkable, that the Q classes get compiled correctly in that case. They appear in the target folder as .class files as they should. Could it be, that the Q classes are compiled too late?
Here is an excerpt of the pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
[...]
<prerequisites>
<maven>3.0.0</maven>
</prerequisites>
<dependencies>
[...]
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>4.1.3</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>4.1.3</version>
</dependency>
</dependencies>
<build>
<defaultGoal>spring-boot:run</defaultGoal>
<plugins>
[...]
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>1.1.3</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/java</outputDirectory>
<processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
[...]
</build>
</project>
This is the configuration of the eclipse project settings:
This is the error message which is displayed in the console:
[INFO] --- maven-processor-plugin:2.2.4:process (process) # project1 ---
[ERROR] diagnostic: C:\Users\user1\git\project1\src\main\java\com\project1\repository\UserRepositoryImpl.java:3: error: cannot find symbol
import static com.project1.domain.QUser.user;
^
symbol: class QUser
location: package com.project1.domain
[ERROR] diagnostic: C:\Users\user1\git\project1\src\main\java\com\project1\repository\UserRepositoryImpl.java:3: error: static import only from classes and interfaces
import static com.project.domain.QUser.user;
^
This is old question but this is how i find my solution, added classifier for jpa dependency:
<!-- BEGIN: 'querydsl-jpa' -->
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>${querydsl-jpa.version}</version>
<classifier>apt</classifier>
</dependency>
<!-- END: 'querydsl-jpa' -->
My complete pom:
<!-- BEGIN: BUILD -->
<build>
<!-- BEGIN: PLUGINS -->
<plugins>
<!-- BEGIN: apt-maven-plugin -->
<plugin>
<groupId>com.mysema.maven</groupId>
<artifactId>apt-maven-plugin</artifactId>
<version>${apt.version}</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
<configuration>
<outputDirectory>target/generated-sources/apt</outputDirectory>
<processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>
</configuration>
</execution>
</executions>
</plugin>
<!-- END: apt-maven-plugin -->
</plugins>
<!-- END: PLUGINS -->
</build>
<!-- END: BUILD -->
<!-- BEGIN: DEPENDENCIES -->
<dependencies>
<!-- *********************************************** -->
<!-- BEGIN: 'QUERYDSL DEPENDENCIES' -->
<!-- BEGIN: 'querydsl-apt' -->
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>${querydsl-apt.version}</version>
</dependency>
<!-- END: 'querydsl-apt' -->
<!-- BEGIN: 'querydsl-jpa' -->
<dependency>
<groupId>com.mysema.querydsl</groupId>
<artifactId>querydsl-jpa</artifactId>
<version>${querydsl-jpa.version}</version>
<classifier>apt</classifier>
</dependency>
<!-- END: 'querydsl-jpa' -->
<!-- *********************************************** -->
<!-- END: 'QUERYDSL DEPENDENCIES' -->
</dependencies>
For me, it didn't work because it conflicted with maven-compiler-plugin with already set annotation processor. Just deleted the use of apt-maven-plugin and added its annotation processor in maven-compiler-plugin.
<build>
<plugins>
<!-- related to issues:-->
<!-- - https://github.com/querydsl/querydsl/issues/2654 -->
<!-- - https://github.com/querydsl/querydsl/issues/2242 -->
<!-- Using apt-maven-plugin conflicts with other annotation processors (like mapStruct) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
<path>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-apt</artifactId>
<version>5.0.0</version>
<classifier>jpa</classifier>
</path>
<path>
<groupId>jakarta.persistence</groupId>
<artifactId>jakarta.persistence-api</artifactId>
<version>2.2.3</version>
</path>
<path>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</path>
<!-- other annotation processors -->
</annotationProcessorPaths>
</configuration>
</plugin>
<!-- <plugin>-->
<!-- <groupId>com.mysema.maven</groupId>-->
<!-- <artifactId>apt-maven-plugin</artifactId>-->
<!-- <version>1.1.3</version>-->
<!-- <executions>-->
<!-- <execution>-->
<!-- <goals>-->
<!-- <goal>process</goal>-->
<!-- </goals>-->
<!-- <configuration>-->
<!-- <outputDirectory>target/generated-sources</outputDirectory>-->
<!-- <processor>com.mysema.query.apt.jpa.JPAAnnotationProcessor</processor>-->
<!-- </configuration>-->
<!-- </execution>-->
<!-- </executions>-->
<!-- </plugin>-->
</plugins>
</build>
But there is an issue with using querydsl annotation processor in maven-compiler-plugin. You have to add jakarta.persistence-api and javax.annotation-api.
I would rather use profile to generate these Qclasses only when db change occurs.
cons:
-your diff in pull requests is clean when you don't change db schema because for each generation these files tend to generate differently for some reason (atleast in my case).
-you can manage witch of tables present in your db will have Qclasses (sometimes it is a pain when you forget to regenerate them after changing db schema)
-well not that it is lots of time . but builds are faster if You don't change schema and profile is turned off.
Try something like this and turn on profile when You want to generate changed schema Qclasses :
<properties>
<whitelisted.tables>
user_accunt,
other
</whitelisted.tables>
</properties>
<profiles>
<profile>
<id>generate</id>
<build>
<plugins>
<plugin>
<groupId>com.querydsl</groupId>
<artifactId>querydsl-maven-plugin</artifactId>
<version>${querydsl.version}</version>
<executions>
<execution>
<goals>
<goal>export</goal>
</goals>
</execution>
</executions>
<configuration>
<jdbcDriver>org.postgresql.Driver</jdbcDriver>
<jdbcUrl>jdbc:postgresql://localhost:port/dbname</jdbcUrl>
<packageName>your.package.name.for.q</packageName>
<jdbcUser>dbusername</jdbcUser>
<jdbcPassword>dbpassword</jdbcPassword>
<targetFolder>${project.basedir}/src/main/java/</targetFolder>
<spatial>true</spatial>
<tableNamePattern>${whitelisted.tables}</tableNamePattern>
</configuration>
<dependencies>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>42.1.1</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</profile>
</profiles>
The generated-source directory are not automatically included in the jar.
You need to use the Maven build helper plugin to fix this issue, for example:
https://github.com/alexec/javahelp-skeleton/blob/master/pom.xml
You can try out few things:
1.try to put <clearOutputDir>false</clearOutputDir> in your configuration tag
2. Sometimes classes might not be getting generated before the compile phase. So try to put phase in your plugin
<execution>
<phase>generate-sources</phase>
<goals>
<goal>...</goal>
</goals>
</execution>
By convention Maven assumes all source code is in 'src/main/java', compiles this and put all *.class file in target.
So if you have a class 'Alien.java' in <project-root>/alice/in/wonderland, your won't be able to access it (in src/main/java) because maven puts everything from src/main/java in classpath for your compiler and hence compiler is unaware of any source code (*.java) anywhere else.
In your case you are generating your source code in directory target/generated-sources/java, so you will have to tell maven about it. As mentioned in some other answers you may use build-helper-plugin for this, let maven know that your source resides on target/generated-sources/java by
<project>
...
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>build-helper-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>add-source</id>
<phase>generate-sources</phase>
<goals>
<goal>add-source</goal>
</goals>
<configuration>
<sources>
<source>target/generated-sources/java</source>
<source>alice/in/wonderland</source>
</sources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Edit: You have mentioned wrong path in build-helper-plugin
I see although you are using build helper plugin but you are using wrong path
--- build-helper-maven-plugin:1.9.1:add-source (add-source) # project1 ---
[INFO] Source directory: C:\Users\user1\git\project1\src\main\generated added.
Instead of src\main\generated you should use <source>target/generated-sources/java</source>
Is there a specific recommended approach to the inclusion of the spring-boot parent pom into projects that already have a required parent POM?
What do you recommend for projects that need to extend from an organizational parent (this is extremely common and even something many/most projects published to Maven central depending on the feeder repos they come from). Most of the build stuff is related to creating executable JARs (e.g. running embedded Tomcat/Jetty). There are ways to structure things so that you can get all the dependencies without extending from a parent (similar to composition vs. inheritance). You can't get a build stuff that way though.
So is it preferable to include all of the spring-boot parent pom inside of the required parent POM or to simply have a POM dependency within the project POM file.
Other options?
TIA,
Scott
You can use the spring-boot-starter-parent like a "bom" (c.f. Spring and Jersey other projects that support this feature now), and include it only in the dependency management section with scope=import.That way you get a lot of the benefits of using it (i.e. dependency management) without replacing the settings in your actual parent.
The 2 main other things it does are
define a load of properties for quickly setting versions of dependencies that you want to override
configure some plugins with default configuration (principally the Spring Boot maven plugin). So those are the things you will have to do manually if you use your own parent.
Example provided in Spring Boot documentation:
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
Update 2022-05-29 with 1.5.9.RELEASE.
I have full code and runable example here https://github.com/surasint/surasint-examples/tree/master/spring-boot-jdbi/9_spring-boot-no-parent (see README.txt to see that you can try)
You need this as a basic
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${springframework.boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
But that is not enough, you also need explicitly define goal for spring-boot-maven-plugin (If you use Spring Boot as parent, you do not have to explicitly define this)
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${springframework.boot.version}</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
Otherwise you cannot build as executable jar or war.
Not yet, if you are using JSP, you need to have this:
<properties>
<failOnMissingWebXml>false</failOnMissingWebXml>
</properties>
Otherwise, you will get this error message:
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-war-plugin:2.2:war (default-war) on project spring-boot-09: Error assembling WAR: webxml attribute is required (or pre-existing WEB-INF/web.xml if executi
ng in update mode) -> [Help 1]
NO NO , this is still not enough if you are using Maven Profile and Resource Filter with Spring Boot with "#" instead of "${}" (like this example https://www.surasint.com/spring-boot-maven-resource-filter/). Then you need to explicitly add this in
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
And this in
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>2.7</version>
<configuration>
<delimiters>
<delimiter>#</delimiter>
</delimiters>
<useDefaultDelimiters>false</useDefaultDelimiters>
</configuration>
</plugin>
See the example in the link https://www.surasint.com/spring-boot-with-no-parent-example/.
As per Surasin Tancharoen's answer, you may also want to define maven surefire plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>${maven-surefire-plugin.version}</version>
</plugin>
and possibly include fail-fast plugin
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${maven-failsafe-plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
There is a class in a maven dependency that is incompatible with Java 8.
How do you properly fix that problem?
Right now I'm doing the following:
Create a package with the same name
Create a class with the same name in that package
Copy and paste the code
Fix the incompatible API call
The problem is that this class contains API calls to restricted classes and although I changed the Eclipse compiler settings (Window -> Preferences -> Java -> Compiler -> Error/Warnings -> Deprecated and restricted API -> Forbidden reference (access rule): Error -> Warning) to allow access the project will only compile sometimes. If it doesn't compile I'll get a "can't find symbol" error.
Edit:
Here are the details you asked for:
Dependency: http://mvnrepository.com/artifact/com.sun.xml.wss/xws-security/3.0
Class: EncryptionProcessor
Necessary change:
// Change line 1053 FROM:
// _dataEncryptor = XMLCipher.getInstance(dataEncAlgo, _dataCipher);
// TO:
_dataEncryptor = XMLCipher.getInstance(dataEncAlgo);
Edit-2:
Maven build error:
[ERROR] symbol: class XMLCipher
[ERROR] location: class com.sun.xml.wss.impl.apachecrypto.EncryptionProcessor
[ERROR] /C:/Users/{name}/development/eclipse_workspace/git/xws-security/src/main/java/com/sun/xml/wss/impl/apachecrypto/EncryptionProcessor.java:[1482,98] cannot find symbol
Here is a detailed guide describing what I did exactly:
Create new Maven project in Eclipse
Configure Maven settings of new project (Important: Use the same group and artifact ID and only change the version number)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.sun.xml.wss</groupId>
<artifactId>xws-security</artifactId>
<version>3.0-java8-fix</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
</project>
Add dependency of bugged JAR
<dependencies>
<dependency>
<groupId>com.sun.xml.wss</groupId>
<artifactId>xws-security</artifactId>
<version>3.0</version>
<exclusions>
<exclusion>
<artifactId>xmldsig</artifactId>
<groupId>javax.xml.crypto</groupId>
</exclusion>
<exclusion>
<artifactId>activation</artifactId>
<groupId>javax.activation</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
Create Java file in the same package of class that needs to be fixed
package com.sun.xml.wss.impl.apachecrypto;
public class EncryptionProcessor {
// The FIX goes here
}
Add Maven shade build plug in to handle creation of patched JAR file (this is not the only plug in to handle this kind of task - e.g. dependency:unpack)
<build>
<plugins>
<!-- plug in for creation of patched JAR file -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<filters>
<filter>
<artifact>com.sun.xml.wss:xws-security:3.0</artifact>
<includes>
<include>**/*.class</include>
<include>**/*.xml</include>
</includes>
<excludes>
<exlude>
com/sun/xml/wss/impl/apachecrypto/EncryptionProcessor.class
</exlude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
Include patched JAR in other projects as necessary (Note: If you experience ClassNotFoundExceptions or similar errors do this: Right-click on the project -> Properties -> Maven -> "Resolve dependencies from Workspace projects":false)
In case you are not familiar with Maven. Here is the complete pom.xml: http://pastebucket.com/88444
Similar to Steven S.'s answer, but using the maven-dependency-plugin. Based on this blog post.
I changed the name of the patched library (not the version), but it depends on your needs what works better for you.
The dependency on the original library should be marked as <optional>true</optional>. Otherwise, the projects that depend on your patched library will also depend on the original library, which means that both the patched and the original version will be on the classpath, which can lead to all kinds of problems.
If your project is a child project, you can still use a completely different groupId and version than your parent pom. Doesn't matter.
You can exclude the classes you patch from unpacking, but it's probably not necessary, because Maven will first unpack the original library and then compile your new version, which means that the original classes are overwritten. Nice!
<?xml version="1.0"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<!-- remove this if you don't have a parent pom -->
<parent>
<groupId>my.company</groupId>
<artifactId>my.company</artifactId>
<version>1.2.3</version>
<relativePath>../pom.xml</relativePath>
</parent>
<groupId>com.foo</groupId>
<artifactId>foo-bar-patched</artifactId>
<version>4.5.6</version>
<build>
<plugins>
<plugin>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.foo</groupId>
<artifactId>foo-bar</artifactId>
<outputDirectory>${project.build.directory}/classes</outputDirectory>
<!-- excludes are probably not necessary -->
<!-- <excludes>**/Foo.class,**/Bar.class</excludes> -->
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>com.foo</groupId>
<artifactId>foo-bar</artifactId>
<version>4.5.6</version>
<optional>true</optional>
</dependency>
</dependencies>
</project>
General solution:
download all project sources
apply your modification
use version control so that change isn't lost
change version in pom.xml, for example from 3.0 to 3.0-patched
launch maven build
copy generated artifacts to you repository/Artifactory, if you use one
change dependency version in your own project