Read Java build path entries inside a Maven project - java

I have a project which has dependencies in its classpath (Java buildpath). Now I have converted it to maven project and compiling it using my customized Maven plugin. Following will be my POM file -
<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.test</groupId>
<artifactId>test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>ear</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>com.my.maven.plugin</groupId>
<artifactId>my-maven-plugin</artifactId>
<version>0.0.1</version>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
</project>
And in my-maven-plugin, I have overridden compile phase -
maven-plugin pom-
<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.test</groupId>
<artifactId>my-maven-plugin</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>maven-plugin</packaging>
<name>my-maven-plugin</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>3.3.9</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-plugin-api</artifactId>
<version>3.3.9</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-compat</artifactId>
<version>3.3.9</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-embedder</artifactId>
<version>3.3.9</version>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-archiver</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
<version>3.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>maven-surefire-common</artifactId>
<version>2.19.1</version>
</dependency>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-api</artifactId>
<version>2.19.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.plexus</groupId>
<artifactId>plexus-component-annotations</artifactId>
<version>1.6</version>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.maven.surefire</groupId>
<artifactId>surefire-junit47</artifactId>
<version>2.19.1</version>
</dependency>
</dependencies>
</project>
lifecycle.xml -
<?xml version="1.0" encoding="UTF-8"?>
<lifecycles>
<lifecycle>
<id>customLifeCycle</id>
<phases>
<phase>
<id>compile</id>
<executions>
<execution>
<goals>
<goal>mycompile</goal>
</goals>
</execution>
</executions>
</phase>
</phases>
</lifecycle>
</lifecycles>
components.xml
<?xml version="1.0" encoding="UTF-8"?>
<component-set>
<components>
<component>
<role>org.apache.maven.artifact.handler.ArtifactHandler</role>
<role-hint>ear</role-hint>
<implementation>org.apache.maven.artifact.handler.DefaultArtifactHandler</implementation>
<configuration>
<type>ear</type>
<extension>ear</extension>
<language>java</language>
<packaging>ear</packaging>
</configuration>
</component>
<component>
<role>org.apache.maven.lifecycle.mapping.LifecycleMapping</role>
<role-hint>ear</role-hint>
<implementation>org.apache.maven.lifecycle.mapping.DefaultLifecycleMapping</implementation>
<configuration>
<phases>
<process-resources>org.apache.maven.plugins:maven-resources-plugin:resources</process-resources>
<compile>com.test:my-maven-plugin:mycompile</compile>
<process-test-resources>org.apache.maven.plugins:maven-resources-plugin:testResources</process-test-resources>
<test-compile>org.apache.maven.plugins:maven-compiler-plugin:testCompile</test-compile>
<test>org.apache.maven.plugins:maven-surefire-plugin:test</test>
<install>org.apache.maven.plugins:maven-install-plugin:install</install>
<deploy>org.apache.maven.plugins:maven-deploy-plugin:deploy</deploy>
</phases>
</configuration>
</component>
</components>
</component-set>
And , overridden compile mojo -
#Mojo( name = "mycompile", defaultPhase = LifecyclePhase.COMPILE )
public class MyCompileMojo extends AbstractMojo{
#Parameter( defaultValue = "${project}", readonly = true, required = true )
private MavenProject project;
public void execute() throws MojoExecutionException, MojoFailureException {
}
}
Now, in compile phase, I want a list of JAR files which are present in classpath. How can I get it? I have tried following - but most of them returns target folder path and classes folder path
List<String> list1 = project.getCompileClasspathElements();
List<String> list2 = project.getRuntimeClasspathElements();
List<String> list3 = project.getSystemClasspathElements();
List<String> list4 = project.getTestClasspathElements();
List<Dependency> list5 = project.getCompileDependencies();
Properties list6 = project.getProperties();
List<Dependency> list7 = project.getSystemDependencies();
List<Dependency> list8 = project.getRuntimeDependencies();
My project structure to be compiled

The key ingredient you're missing is requiresDependencyResolution, which represent the set of dependencies that will be made available to the plugin. From the Mojo API reference:
Flags this Mojo as requiring the dependencies in the specified class path to be resolved before it can execute. [...] If the annotation is not present at all, the mojo must not make any assumptions about the artifacts associated with a Maven project.
To have access to the compile-time dependencies of the project, you can use ResolutionScope.COMPILE:
compile resolution scope = compile + system + provided dependencies
Among others, there is also COMPILE_PLUS_RUNTIME to have access to runtime scoped dependencies as well, or TEST to add the test scoped dependencies. When this parameter is not present for the Maven plugin, no classpath elements of the Maven project will be available to it, which is the behaviour you encountered.
Therefore, if you want the Maven plugin to get hold of the list of the compile-tile JAR files which are the dependencies of the current Maven project, you can have:
#Mojo(name = "mycompile", defaultPhase = LifecyclePhase.COMPILE, requiresDependencyResolution = ResolutionScope.COMPILE)
public class MyCompileMojo extends AbstractMojo {
#Parameter(defaultValue = "${project}", readonly = true, required = true)
private MavenProject project;
public void execute() throws MojoExecutionException, MojoFailureException {
try {
List<String> list = project.getCompileClasspathElements();
getLog().info(list.toString());
} catch (DependencyResolutionRequiredException e) {
throw new MojoFailureException("Couldn't resolve compile dependencies", e);
}
}
}
The method getCompileClasspathElements() returns the list of path to the JAR files of each compile-time dependencies. It will also contain the path to the target/classes folder of the current Maven project, because it contains the compiled main Java sources of the project. The code above would simply print this list. Similarly, you would use getTestClasspathElements() together with ResolutionScope.TEST to have the list of test scoped dependencies, as well as compile-time dependencies.
If you only want the path to the JAR file of the dependencies, without the classes of the project itself, you can use the method getArtifacts() instead:
public void execute() throws MojoExecutionException, MojoFailureException {
Set<Artifact> artifacts = project.getArtifacts();
for (Artifact artifact : artifacts) {
System.out.println(artifact.getFile());
}
}
Note that for this to work, you need to make sure the compile phase (or test-compile) has run. The lists are lazily-populated. Running mvn clean test will make sure the plugin has access to the test scope dependencies if it declared a requiresDependencyResolution of TEST. Similarly, running mvn clean compile (along with changing the phase to <phase>compile</phase>) will make sure the plugin has access to the compile scope dependencies if it declared a requiresDependencyResolution of COMPILE.
Couple of side-notes:
The file lifecycle.xml has to be located inside src/main/resources/META-INF/maven. Note that this file is actually completely unused in your set-up, because you did not use the new customLifeCycle inside your components.xml, and override ear instead;
The file components.xml has to be located inside src/main/resources/META-INF/plexus. Note that the <compile>com.test:my-maven-plugin:mycompile</compile> has to match the group id and artifact id of the plugin;
The test project needs to use the plugin like so:
<packaging>ear</packaging> <!-- because your lifecycle mapping override ear -->
<dependencies>
<!-- some dependencies like maven-core -->
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
<version>3.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.test</groupId>
<artifactId>my-maven-plugin</artifactId>
<version>0.0.1-SNAPSHOT</version>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
Then you can run mvn clean package and the plugin will correctly prints the path to JAR files of maven-core (for example) and its dependencies.

This worked for me.
I found it here https://www.mkyong.com/java/how-to-print-out-the-current-project-classpath/
package com.mkyong.io;
import java.net.URL;
import java.net.URLClassLoader;
public class App{
public static void main (String args[]) {
ClassLoader cl = ClassLoader.getSystemClassLoader();
URL[] urls = ((URLClassLoader)cl).getURLs();
for(URL url: urls){
System.out.println(url.getFile());
}
}
}

In completion to the previous answer, you can read all Class-Path like that :
public static List<String> getClassPaths() {
List<String> list = new ArrayList<String>();
Enumeration res;
try {
res = Thread.currentThread().getContextClassLoader().getResources(JarFile.MANIFEST_NAME);
while (res.hasMoreElements()) {
try {
URL url = (URL)res.nextElement();
InputStream is = url.openStream();
if (is != null) {
Manifest manifest = new Manifest(is);
Attributes mainAttribs = manifest.getMainAttributes();
String classpath = mainAttribs.getValue("Class-Path");
if (classpath != null)
list.add(classpath);
}
}
catch (Exception e) {
// Silently ignore wrong manifests or stop the compilation
}
}
} catch (IOException e1) {
// Silently ignore wrong manifests or stop the compilation
}
return list;
}
If you need to go deeper into dependencies:
public static List<String> getClassPaths() {
List<String> list = new ArrayList<String>();
Enumeration res;
try {
res = Thread.currentThread().getContextClassLoader().getResources(JarFile.MANIFEST_NAME);
while (res.hasMoreElements()) {
try {
URL url = (URL)res.nextElement();
InputStream is = url.openStream();
if (is != null) {
Manifest manifest = new Manifest(is);
Attributes mainAttribs = manifest.getMainAttributes();
String classpath = mainAttribs.getValue("Class-Path");
if (classpath != null)
for (String lib : classpath.split(" ")) {
try {
list.addAll(getClassPathsFromJar(lib));
} catch (IOException ioe)
{
list.add(lib);
}
}
}
}
catch (Exception e) {
// Silently ignore wrong manifests or stop the compilation
}
}
} catch (IOException e1) {
// Silently ignore wrong manifests or stop the compilation
}
return list;
}
public static List<String> getClassPathsFromJar(String lib) throws IOException {
List<String> entries = new ArrayList<String>();
JarFile jar = new JarFile(lib);
Manifest manifest = jar.getManifest();
if (manifest == null) {
entries.add(lib);
return entries;
}
Attributes mainAttribs = manifest.getMainAttributes();
String classpath = mainAttribs.getValue("Class-Path");
if (classpath == null) {
entries.add(lib);
return entries;
}
for (String l : classpath.split(" ")) {
entries.addAll(getClassPathsFromJar(l));
}
return entries;
}

Related

How do I remove the ns2 prefixes from XML elements using JAXB 3 and a NamespacePrefixMapper?

I want to generate a POM file using JAXB 3. I downloaded the XSD https://maven.apache.org/xsd/maven-4.0.0.xsd into src/main/xsd.
I generated the model classes using the JAXB maven plugin.
The POM file of the project is :
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mycompany.myproject</groupId>
<artifactId>test-maven</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>com.evolvedbinary.maven.mojohaus</groupId>
<artifactId>jaxb-maven-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>xjc</id>
<goals>
<goal>xjc</goal>
</goals>
</execution>
</executions>
<configuration>
<packageName>org.apache.maven.pom</packageName>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>jakarta.xml.bind</groupId>
<artifactId>jakarta.xml.bind-api</artifactId>
<version>3.0.1</version>
</dependency>
<dependency>
<groupId>com.sun.xml.bind</groupId>
<artifactId>jaxb-impl</artifactId>
<version>3.0.1</version>
</dependency>
</dependencies>
</project>
The main class used to generate the sample POM is :
import org.apache.maven.pom.Dependency;
import org.apache.maven.pom.Model;
import org.apache.maven.pom.Model.Dependencies;
import org.glassfish.jaxb.core.v2.WellKnownNamespace;
import org.glassfish.jaxb.runtime.marshaller.NamespacePrefixMapper;
import javax.xml.XMLConstants;
import javax.xml.namespace.QName;
import jakarta.xml.bind.JAXBContext;
import jakarta.xml.bind.JAXBElement;
import jakarta.xml.bind.JAXBException;
import jakarta.xml.bind.Marshaller;
public class Main {
public static void main(String[] args) throws JAXBException {
Model model = new Model();
model.setModelVersion("4.0.0");
model.setDependencies(new Dependencies());
Dependency dependency = new Dependency();
dependency.setGroupId("commons-io");
dependency.setArtifactId("commons-io");
dependency.setVersion("2.11.0");
model.getDependencies().getDependency().add(dependency);
JAXBElement<Model> elem = new JAXBElement<>(new QName("project"), Model.class, model);
JAXBContext context = JAXBContext.newInstance(Model.class);
Marshaller m = context.createMarshaller();
m.setProperty("org.glassfish.jaxb.namespacePrefixMapper", new NamespacePrefixMapper() {
#Override
public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
return switch (namespaceUri) {
case XMLConstants.W3C_XML_SCHEMA_INSTANCE_NS_URI -> "xsi";
case XMLConstants.W3C_XML_SCHEMA_NS_URI -> "xs";
case WellKnownNamespace.XML_MIME_URI -> "xmime";
default -> "";
};
}
});
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,true);
m.marshal(elem, System.out);
}
}
My issue is, the output contains undesired ns2 prefixes. I didn't figure out how to tell the marshaller that the generated model uses the default namespace and not a namespace named ns2.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<project xmlns:ns2="http://maven.apache.org/POM/4.0.0">
<ns2:modelVersion>4.0.0</ns2:modelVersion>
<ns2:dependencies>
<ns2:dependency>
<ns2:groupId>commons-io</ns2:groupId>
<ns2:artifactId>commons-io</ns2:artifactId>
<ns2:version>2.11.0</ns2:version>
</ns2:dependency>
</ns2:dependencies>
</project>
I forgot to provide the namespace to the QName :
new QName("http://maven.apache.org/POM/4.0.0", "project")
And now the result looks good :
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<dependencies>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
</dependencies>
</project>
There's no need for a prefix mapper, so the code can be simplified:
import org.apache.maven.pom.Dependency;
import org.apache.maven.pom.Model;
import org.apache.maven.pom.Model.Dependencies;
import javax.xml.namespace.QName;
import jakarta.xml.bind.JAXB;
import jakarta.xml.bind.JAXBElement;
public class Main {
public static void main(String[] args) {
Model model = new Model();
model.setModelVersion("4.0.0");
model.setDependencies(new Dependencies());
Dependency dependency = new Dependency();
dependency.setGroupId("commons-io");
dependency.setArtifactId("commons-io");
dependency.setVersion("2.11.0");
model.getDependencies().getDependency().add(dependency);
JAXBElement<Model> elem = new JAXBElement<>(new QName("http://maven.apache.org/POM/4.0.0", "project"), Model.class, model);
JAXB.marshal(elem, System.out);
}
}

Error deploying with heroku java.lang.NoClassDefFoundError: jakarta/servlet/jsp/tagext/TagLibraryValidator

I am trying to deploy my webapp in java with heroku, I implement this simple example:
package launch;
import java.io.File;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import org.apache.catalina.WebResourceRoot;
import org.apache.catalina.WebResourceSet;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.webresources.DirResourceSet;
import org.apache.catalina.webresources.EmptyResourceSet;
import org.apache.catalina.webresources.StandardRoot;
public class Main {
private static File getRootFolder() {
try {
File root;
String runningJarPath = Main.class.getProtectionDomain().getCodeSource().getLocation().toURI().getPath().replaceAll("\\\\", "/");
int lastIndexOf = runningJarPath.lastIndexOf("/target/");
if (lastIndexOf < 0) {
root = new File("");
} else {
root = new File(runningJarPath.substring(0, lastIndexOf));
}
System.out.println("application resolved root folder: " + root.getAbsolutePath());
return root;
} catch (URISyntaxException ex) {
throw new RuntimeException(ex);
}
}
public static void main(String[] args) throws Exception {
File root = getRootFolder();
System.setProperty("org.apache.catalina.startup.EXIT_ON_INIT_FAILURE", "true");
Tomcat tomcat = new Tomcat();
Path tempPath = Files.createTempDirectory("tomcat-base-dir");
tomcat.setBaseDir(tempPath.toString());
//The port that we should run on can be set into an environment variable
//Look for that variable and default to 8080 if it isn't there.
String webPort = System.getenv("PORT");
if (webPort == null || webPort.isEmpty()) {
webPort = "8080";
}
tomcat.setPort(Integer.valueOf(webPort));
File webContentFolder = new File(root.getAbsolutePath(), "src/main/webapp/");
if (!webContentFolder.exists()) {
webContentFolder = Files.createTempDirectory("default-doc-base").toFile();
}
StandardContext ctx = (StandardContext) tomcat.addWebapp("", webContentFolder.getAbsolutePath());
//Set execution independent of current thread context classloader (compatibility with exec:java mojo)
ctx.setParentClassLoader(Main.class.getClassLoader());
System.out.println("configuring app with basedir: " + webContentFolder.getAbsolutePath());
// Declare an alternative location for your "WEB-INF/classes" dir
// Servlet 3.0 annotation will work
File additionWebInfClassesFolder = new File(root.getAbsolutePath(), "target/classes");
WebResourceRoot resources = new StandardRoot(ctx);
WebResourceSet resourceSet;
if (additionWebInfClassesFolder.exists()) {
resourceSet = new DirResourceSet(resources, "/WEB-INF/classes", additionWebInfClassesFolder.getAbsolutePath(), "/");
System.out.println("loading WEB-INF resources from as '" + additionWebInfClassesFolder.getAbsolutePath() + "'");
} else {
resourceSet = new EmptyResourceSet(resources);
}
resources.addPreResources(resourceSet);
ctx.setResources(resources);
tomcat.start();
tomcat.getServer().await();
}
}
and my jsp
<%# page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%# taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<body>
<h2>Hola Mundo!</h2>
pincha aca
<c:if test="${true}">
<h3>Hola</h3>
</c:if>
</body>
</html>
when I include the jstl in my project after doing the deploy it throws this exception:
java.lang.NoClassDefFoundError: jakarta/servlet/jsp/tagext/TagLibraryValidator
my pom
<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>
<groupId>com.heroku.sample</groupId>
<artifactId>embeddedTomcatSample</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>embeddedTomcatSample Maven Webapp</name>
<url>http://maven.apache.org</url>
<properties>
<tomcat.version>8.5.38</tomcat.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper-el</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jsp-api</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.glassfish.web</groupId>
<artifactId>jakarta.servlet.jsp.jstl</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>embeddedTomcatSample</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>2.0.0</version>
<configuration>
<assembleDirectory>target</assembleDirectory>
<programs>
<program>
<mainClass>launch.Main</mainClass>
<name>webapp</name>
</program>
</programs>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>assemble</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
and my Procfile
web: sh target/bin/webapp
I tried everything but nothing worked. Please help.
jakarta servlet is supported only in tomcat 10 version.
More so Heroku supports webapp-runner for tomcat 9.0.68.0, as of Oct 2022.
So the error.
Even if you deploy with 9.0.68.0, the code will fail for want of jakarta servlet.
https://docs.oracle.com/javaee/5/jstl/1.1/docs/tlddocs/c/tld-summary.html
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

How to add file .properties to spring boot with maven (Build Jar)?

I'm developing a web app with spring boot, I built the project with Maven.
In the project I use files .properties and I gave the path of the project like this:
Properties FileProperties = FileUtils.getProperties("src\main\resources\file.properties");
Running the project with IntelliJ, all work.
But at the moment I built with maven in Jar, and I open the web app, don't find the file properties and give NullPointerException.
This is my pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.9</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
This is the project map.
https://m.imgur.com/gallery/zZzTzID
Thanks so much
I tried this, but dont work.
ConfigProperties.java
package bperTube.transfer.Utils;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
#Configuration
#PropertySource("classpath:file.properties")
#ConfigurationProperties(prefix = "upload")
public class ConfigProperties {
private String dateFormat;
private String directoryPath;
private String videoDirectory;
private String imageDirectory;
public String getDateFormat() {
return dateFormat;
}
public void setDateFormat(String dateFormat) {
this.dateFormat = dateFormat;
}
public String getDirectoryPath() {
return directoryPath;
}
public void setDirectoryPath(String directoryPath) {
this.directoryPath = directoryPath;
}
public String getVideoDirectory() {
return videoDirectory;
}
public void setVideoDirectory(String videoDirectory) {
this.videoDirectory = videoDirectory;
}
public String getImageDirectory() {
return imageDirectory;
}
public void setImageDirectory(String imageDirectory) {
this.imageDirectory = imageDirectory;
}
}
file.properties
upload.dateFormat=dd-MM-yyyy
upload.directoryPath=/test/
upload.videoDirectory=swf/
upload.imageDirectory=poster/

How to package multiple Spring-boot jar in one jar

There are two spring-boot project like after:
service_one
service_two
they all can run success alone.
Now I had changed this way, I use service_all project to manage which services should run: such as jvm properties. The final project like after
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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.demo.service</groupId>
<artifactId>service_all</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>service_all</name>
<dependencies>
<dependency>
<groupId>com.demo.service</groupId>
<artifactId>service_one</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>com.demo.service</groupId>
<artifactId>service_two</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.1.0.RELEASE</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
// Java class in service_all
#Slf4j
#SpringBootApplication
public class Application {
public static void main(String[] args) throws IOException {
/**
* Common
*/
ConfigurableApplicationContext commonContext =
new SpringApplicationBuilder(Application.class).web(WebApplicationType.NONE).run(args);
log.info(commonContext.getId() + " isActive: " + commonContext.isActive());
/**
* service_one
*/
if (commonContext.getEnvironment().containsProperty("service_one")) {
ConfigurableApplicationContext oneContext =
new SpringApplicationBuilder(ServiceOneApplication.class)
.parent(commonContext)
.sources(RefreshScope.class).run(args);
log.info(configContext.getId() + " isActive: " + oneContext.isActive());
}
/**
* service_two
*/
if (commonContext.getEnvironment().containsProperty("service_two")) {
ConfigurableApplicationContext twoContext =
new SpringApplicationBuilder(ServiceTwoApplication.class).parent(commonContext)
.sources(RefreshScope.class).run(args);
log.info(adminContext.getId() + " isActive: " + twoContext.isActive());
}
}
}
Now I can't package the service_one and service_two lib in service_all jar's lib.
So how can I resolve this?
PS:
I can't change service_one and service_two anything, only can use like a dependency;
I can't use maven parent;

querying ldap server with java unboundid-ldapsdk

I have setup an ldap server with Apache director studio:
This is my code:
import com.unboundid.asn1.ASN1OctetString;
import com.unboundid.ldap.sdk.*;
import com.unboundid.ldap.sdk.controls.SimplePagedResultsControl;
public class App {
/**
* #param args
* #throws LDAPException
*/
public static void main(String[] args) throws LDAPException {
LDAPConnection connection = new LDAPConnection("localhost", 10389, "uid=admin,ou=system","secret");//"cn=admin4directory,dc=ilex-si,dc=eu", "M3d2p5a4!");
//SearchRequest searchRequest = new SearchRequest("ou=people,dc=ilex-si,dc=eu", SearchScope.SUB,"(ixuid=*)");
SearchRequest searchRequest = new SearchRequest("ou=people,dc=example,dc=com", SearchScope.BASE,Filter.createEqualityFilter("objectClass", "person"));
ASN1OctetString cookie = null;
do
{
searchRequest.setControls(
new Control[] { new SimplePagedResultsControl(500, cookie) });
SearchResult searchResult = connection.search(searchRequest);
// Do something with the entries that are returned.
cookie = null;
for (Control c : searchResult.getResponseControls())
{
if (c instanceof SimplePagedResultsControl)
{
cookie = ((SimplePagedResultsControl) c).getCookie();
System.out.println("\ncookie = "+ cookie.toString());
}
}
} while ((cookie != null) && (cookie.getValueLength() > 0));
connection.close();
}
}
I want to do a paged query but with this code I have returned a blank cookie..
How can I print the cn = john smit and cn robert smith values??
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>it.abc</groupId>
<artifactId>LDAPPagedQueryExample</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>LDAPPagedQueryExample</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.mule.tools</groupId>
<artifactId>maven-mule-plugin</artifactId>
<version>1.6</version>
<extensions>true</extensions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.unboundid</groupId>
<artifactId>unboundid-ldapsdk</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
Thank you.
Have you tried the simple example at https://docs.ldap.com/ldap-sdk/docs/javadoc/com/unboundid/ldap/sdk/controls/SimplePagedResultsControl.html
For sure You SearchScope.BASE must be at LEAST SearchScope.ONE or better SearchScope.SUB.
Not sure what is implied "How can I print the cn = john smit and cn robert smith values??"

Categories