Test Apache Felix with Java 8 and JavaFX - osgi
I'm working on example with JavaFX 2.2 and Java 8. I created this simple Apache Felix Activator:
Activator:
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class Activator implements BundleActivator
{
Stage stage;
#Override
public void start(BundleContext context) throws Exception
{
Platform.runLater(new Runnable()
{
#Override
public void run()
{
stage = new Stage();
BorderPane pane = new BorderPane();
Scene scene = new Scene(pane, 400, 200);
pane.setCenter(new Label("This is a JavaFX Scene in a Stage"));
stage.setScene(scene);
stage.show();
}
});
System.out.println("Main Module is loaded!");
}
#Override
public void stop(BundleContext context) throws Exception
{
Platform.runLater(new Runnable()
{
#Override
public void run()
{
stage.close();
}
});
System.out.println("Main Module is unloaded!");
}
}
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>DX-57</groupId>
<artifactId>DX-57_Main</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>bundle</packaging>
<name>DX-57_Main OSGi Bundle</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<version>5.0.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.7</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Import-Package>*</Import-Package>
<Bundle-Activator>dx57.dx._main.Activator</Bundle-Activator>
<Export-Package>*</Export-Package>
</instructions>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>build-for-felix</id>
<dependencies>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.main</artifactId>
<version>4.2.1</version>
<scope>provided</scope>
</dependency>
<!-- To include a shell:
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.gogo.shell</artifactId>
<version>0.10.0</version>
</dependency>
-->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<executions>
<execution>
<id>compile</id>
<phase>package</phase>
<goals>
<goal>run</goal>
</goals>
<configuration>
<target>
<pathconvert property="plugins.jars" pathsep="${path.separator}">
<path refid="maven.runtime.classpath"/>
<map from="${project.build.directory}${file.separator}classes" to=""/>
</pathconvert>
<pathconvert pathsep=" " property="bundles">
<path path="${plugins.jars}"/>
<mapper>
<chainedmapper>
<flattenmapper/>
<globmapper from="*" to="file:modules/*" casesensitive="no"/>
</chainedmapper>
</mapper>
</pathconvert>
<propertyfile file="${project.build.directory}/config.properties">
<entry key="felix.auto.start" value="${bundles} file:modules/${project.build.finalName}.jar"/>
<entry key="org.osgi.framework.bootdelegation" value="*"/>
</propertyfile>
<copy file="${maven.dependency.org.apache.felix.org.apache.felix.main.jar.path}" tofile="${project.build.directory}/felix.jar"/>
</target>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.4</version>
<executions>
<execution>
<id>create-executable-jar</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptors>
<descriptor>${basedir}/src/main/assembly/felix.xml</descriptor>
</descriptors>
<finalName>${project.build.finalName}</finalName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>run-on-felix</id>
<dependencies>
<dependency>
<groupId>org.apache.felix</groupId>
<artifactId>org.apache.felix.main</artifactId>
<version>4.2.1</version>
<scope>provided</scope>
</dependency>
<!-- org.apache.felix:org.apache.felix.gogo.shell:0.6.1 useless from Maven since stdin is swallowed -->
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<version>1.7</version>
<configuration>
<target>
<property name="vm.args" value=""/>
<pathconvert property="plugins.jars" pathsep="${path.separator}">
<path refid="maven.runtime.classpath"/>
<map from="${project.build.directory}${file.separator}classes" to=""/>
</pathconvert>
<makeurl property="urls" separator=" ">
<path path="${plugins.jars}"/>
<path location="${project.build.directory}/${project.build.finalName}.jar"/>
</makeurl>
<propertyfile file="${project.build.directory}/run.properties">
<entry key="felix.auto.start" value="${urls}"/>
<entry key="felix.auto.deploy.action" value="uninstall,install,update,start"/>
<entry key="org.osgi.framework.storage" value="${project.build.directory}${file.separator}felix-cache"/>
<entry key="org.osgi.framework.bootdelegation" value="*"/>
</propertyfile>
<makeurl property="run.properties.url" file="${project.build.directory}/run.properties"/>
<java fork="true" jar="${maven.dependency.org.apache.felix.org.apache.felix.main.jar.path}">
<sysproperty key="felix.config.properties" value="${run.properties.url}"/>
<jvmarg line="${vm.args}"/>
</java>
</target>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
Error:
[rcbandit#Laptop felix-framework_JavaFX]$ /opt/jdk1.8.0/bin/java -jar bin/felix.jar
ERROR: Bundle DX-57.Main [1] Error starting file:/home/rcbandit/Desktop/test/felix-framework_JavaFX/bundle/DX-57_Main-1.0-SNAPSHOT.jar (org.osgi.framework.BundleException: Activator start error in bundle DX-57.Main [1].)
java.lang.ClassCastException: dx57.dx._main.Activator cannot be cast to org.osgi.framework.BundleActivator
at org.apache.felix.framework.Felix.createBundleActivator(Felix.java:4336)
at org.apache.felix.framework.Felix.activateBundle(Felix.java:2141)
at org.apache.felix.framework.Felix.startBundle(Felix.java:2064)
at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1291)
at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:304)
at java.lang.Thread.run(Thread.java:724)
____________________________
Welcome to Apache Felix Gogo
g!
I added external packages into the file config.properties:
org.osgi.framework.system.packages.extra=javafx.application, \
com.sun.browser.plugin, \
com.sun.deploy.uitoolkit.impl.fx, \
com.sun.deploy.uitoolkit.impl.fx.ui, \
com.sun.deploy.uitoolkit.impl.fx.ui.resources, \
com.sun.deploy.uitoolkit.impl.fx.ui.resources.image, \
com.sun.glass.events, \
com.sun.glass.ui, \
com.sun.glass.ui.delegate, \
com.sun.glass.ui.gtk, \
com.sun.glass.ui.mac, \
com.sun.glass.ui.win, \
com.sun.glass.ui.x11, \
com.sun.glass.utils, \
com.sun.javafx, \
com.sun.javafx.animation, \
com.sun.javafx.animation.transition, \
com.sun.javafx.applet, \
com.sun.javafx.application, \
com.sun.javafx.beans, \
com.sun.javafx.beans.annotations, \
com.sun.javafx.beans.event, \
com.sun.javafx.binding, \
com.sun.javafx.charts, \
com.sun.javafx.collections, \
com.sun.javafx.collections.annotations, \
com.sun.javafx.collections.transformation, \
com.sun.javafx.css, \
com.sun.javafx.css.converters, \
com.sun.javafx.css.parser, \
com.sun.javafx.cursor, \
com.sun.javafx.effect, \
com.sun.javafx.embed, \
com.sun.javafx.event, \
com.sun.javafx.font, \
com.sun.javafx.fxml, \
com.sun.javafx.fxml.builder, \
com.sun.javafx.fxml.expression, \
com.sun.javafx.geom, \
com.sun.javafx.geom.transform, \
com.sun.javafx.iio, \
com.sun.javafx.iio.bmp, \
com.sun.javafx.iio.common, \
com.sun.javafx.iio.gif, \
com.sun.javafx.iio.jpeg, \
com.sun.javafx.iio.png, \
com.sun.javafx.image, \
com.sun.javafx.image.impl, \
com.sun.javafx.jmx, \
com.sun.javafx.logging, \
com.sun.javafx.menu, \
com.sun.javafx.perf, \
com.sun.javafx.property, \
com.sun.javafx.property.adapter, \
com.sun.javafx.robot, \
com.sun.javafx.robot.impl, \
com.sun.javafx.runtime, \
com.sun.javafx.runtime.async, \
com.sun.javafx.runtime.eula, \
com.sun.javafx.scene, \
com.sun.javafx.scene.control, \
com.sun.javafx.scene.control.behavior, \
com.sun.javafx.scene.control.skin, \
com.sun.javafx.scene.control.skin.caspian, \
com.sun.javafx.scene.control.skin.resources, \
com.sun.javafx.scene.input, \
com.sun.javafx.scene.layout.region, \
com.sun.javafx.scene.paint, \
com.sun.javafx.scene.shape, \
com.sun.javafx.scene.text, \
com.sun.javafx.scene.transform, \
com.sun.javafx.scene.traversal, \
com.sun.javafx.scene.web, \
com.sun.javafx.scene.web.behavior, \
com.sun.javafx.scene.web.skin, \
com.sun.javafx.sg, \
com.sun.javafx.sg.prism, \
com.sun.javafx.stage, \
com.sun.javafx.tk, \
com.sun.javafx.tk.desktop, \
com.sun.javafx.tk.quantum, \
com.sun.javafx.util, \
com.sun.media.jfxmedia, \
com.sun.media.jfxmedia.control, \
com.sun.media.jfxmedia.effects, \
com.sun.media.jfxmedia.events, \
com.sun.media.jfxmedia.locator, \
com.sun.media.jfxmedia.logging, \
com.sun.media.jfxmedia.track, \
com.sun.media.jfxmediaimpl, \
com.sun.media.jfxmediaimpl.platform, \
com.sun.media.jfxmediaimpl.platform.gstreamer, \
com.sun.media.jfxmediaimpl.platform.java, \
com.sun.media.jfxmediaimpl.platform.osx, \
com.sun.openpisces, \
com.sun.prism, \
com.sun.prism.camera, \
com.sun.prism.d3d, \
com.sun.prism.d3d.hlsl, \
com.sun.prism.image, \
com.sun.prism.impl, \
com.sun.prism.impl.packrect, \
com.sun.prism.impl.paint, \
com.sun.prism.impl.ps, \
com.sun.prism.impl.shape, \
com.sun.prism.j2d, \
com.sun.prism.j2d.paint, \
com.sun.prism.paint, \
com.sun.prism.ps, \
com.sun.prism.render, \
com.sun.prism.shader, \
com.sun.prism.shape, \
com.sun.prism.tkal, \
com.sun.prism.util.tess, \
com.sun.prism.util.tess.impl.tess, \
com.sun.scenario, \
com.sun.scenario.animation, \
com.sun.scenario.animation.shared, \
com.sun.scenario.effect, \
com.sun.scenario.effect.impl, \
com.sun.scenario.effect.impl.hw, \
com.sun.scenario.effect.impl.hw.d3d, \
com.sun.scenario.effect.impl.hw.d3d.hlsl, \
com.sun.scenario.effect.impl.prism, \
com.sun.scenario.effect.impl.prism.ps, \
com.sun.scenario.effect.impl.prism.sw, \
com.sun.scenario.effect.impl.state, \
com.sun.scenario.effect.impl.sw, \
com.sun.scenario.effect.impl.sw.java, \
com.sun.scenario.effect.impl.sw.sse, \
com.sun.scenario.effect.light, \
com.sun.t2k, \
com.sun.webpane.perf, \
com.sun.webpane.platform, \
com.sun.webpane.platform.event, \
com.sun.webpane.platform.graphics, \
com.sun.webpane.sg, \
com.sun.webpane.sg.prism, \
com.sun.webpane.sg.prism.resources, \
com.sun.webpane.sg.prism.theme, \
com.sun.webpane.sg.theme, \
com.sun.webpane.webkit, \
com.sun.webpane.webkit.dom, \
com.sun.webpane.webkit.network, \
com.sun.webpane.webkit.network.about, \
com.sun.webpane.webkit.network.data, \
com.sun.webpane.webkit.unicode, \
javafx.animation, \
javafx.beans, \
javafx.beans.binding, \
javafx.beans.property, \
javafx.beans.property.adapter, \
javafx.beans.value, \
javafx.collections, \
javafx.concurrent, \
javafx.embed.swing, \
javafx.embed.swt, \
javafx.event, \
javafx.fxml, \
javafx.geometry, \
javafx.scene, \
javafx.scene.canvas, \
javafx.scene.chart, \
javafx.scene.control, \
javafx.scene.control.cell, \
javafx.scene.effect, \
javafx.scene.image, \
javafx.scene.input, \
javafx.scene.layout, \
javafx.scene.media, \
javafx.scene.paint, \
javafx.scene.shape, \
javafx.scene.text, \
javafx.scene.transform, \
javafx.scene.web, \
javafx.stage, \
javafx.util, \
javafx.util.converter, \
org.osgi.framework.wiring, \
netscape.javascript
Any idea how to fix the problem?
UPDATE
After removing <Export-Package>*</Export-Package> I get this error:
[rcbandit#Laptop felix-framework_JavaFX]$ /opt/jdk1.8.0/bin/java -jar bin/felix.jar
ERROR: Bundle DX-57.Main [1] Error starting file:/home/rcbandit/Desktop/test/felix-framework_JavaFX/bundle/DX-57_Main-1.0-SNAPSHOT.jar (org.osgi.framework.BundleException: Activator start error in bundle DX-57.Main [1].)
java.lang.IllegalStateException: Toolkit not initialized
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:201)
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:196)
at javafx.application.Platform.runLater(Platform.java:52)
at dx57.dx._main.Activator.start(Activator.java:20)
at org.apache.felix.framework.util.SecureAction.startActivator(SecureAction.java:645)
at org.apache.felix.framework.Felix.activateBundle(Felix.java:2146)
at org.apache.felix.framework.Felix.startBundle(Felix.java:2064)
at org.apache.felix.framework.Felix.setActiveStartLevel(Felix.java:1291)
at org.apache.felix.framework.FrameworkStartLevelImpl.run(FrameworkStartLevelImpl.java:304)
at java.lang.Thread.run(Thread.java:724)
____________________________
Welcome to Apache Felix Gogo
g!
JavaFX applications depend on packages from the JavaFX APIs, such as javafx.application and several others. Since it looks like you have built your bundle with Maven Bundle Plugin, your bundle already has these dependencies declared. This is a good thing.
In Java 8 the javafx.* packages are provided by the base JRE. However OSGi does not automatically export every package from the JRE, simply because all JREs have a bunch of non-standard packages (e.g. com.sun.* etc) that normal application code should not have access to. Therefore OSGi only makes available the packages that are defined by the relevant JCP Specification for the version of Java that you are using. For example packages such as javax.swing, org.w3c.dom, etc.
Since JavaFX is not a standard, there is no JCP Specification for JavaFX, and OSGi does not export the javafx.* packages. However you can configure OSGi to do this for you by setting the following configuration property when you launch OSGi:
org.osgi.framework.system.packages.extra=javafx.application,...
NB I have shown how to add the javafx.application package to your runtime. It is likely you will need to add several more, i.e. all of the packages from the JavaFX API. I am not sufficiently familar with JavaFX to list these, but they should be easy enough for you to find.
I have recently released a first Early Access version of Drombler FX, a modular Rich Client Platform for JavaFX based on OSGi and Maven (POM-first; uses Apache Felix by default).
You can read more about it here: http://puces-blog.blogspot.ch/2012/12/drombler-fx-building-modular-javafx.html
Getting Startet: http://wiki.drombler.org/GettingStarted
I recenttly tried to run it with a pre-release of Java SE 8 and it worked so far, though I haven't specified the system packages for Java SE 8 yet, so I'm not sure if everything works/ if you have access to everything.
Related
Spring Boot Embedded Tomcat not starting when using spring boot 2.6.2 and above
I start a new spring boot application based on the spring boot 2.6.2. The application is very simple, just helloworld with web-mvc and spring-security. I have done it several times before, but this time the tomcat doesn't start up when the application runs. The pom.xml is as below: <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> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.6.2</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.demo</groupId> <artifactId>spring-demo</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring-demo</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> And the console is as below when the application starts: "C:\Program Files\Java\jdk1.8.0_301\bin\java.exe" -XX:TieredStopAtLevel=1 -noverify -Dspring.output.ansi.enabled=always "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2020.3.2\lib\idea_rt.jar=12156:C:\Program Files\JetBrains\IntelliJ IDEA 2020.3.2\bin" -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_301\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_301\jre\lib\rt.jar;E:\code\example\java\spring-demo\target\classes;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-security\2.6.3\spring-boot-starter-security-2.6.3.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter\2.6.3\spring-boot-starter-2.6.3.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot\2.6.3\spring-boot-2.6.3.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\2.6.3\spring-boot-autoconfigure-2.6.3.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-logging\2.6.3\spring-boot-starter-logging-2.6.3.jar;C:\Users\Administrator\.m2\repository\ch\qos\logback\logback-classic\1.2.10\logback-classic-1.2.10.jar;C:\Users\Administrator\.m2\repository\ch\qos\logback\logback-core\1.2.10\logback-core-1.2.10.jar;C:\Users\Administrator\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.17.1\log4j-to-slf4j-2.17.1.jar;C:\Users\Administrator\.m2\repository\org\apache\logging\log4j\log4j-api\2.17.1\log4j-api-2.17.1.jar;C:\Users\Administrator\.m2\repository\org\slf4j\jul-to-slf4j\1.7.33\jul-to-slf4j-1.7.33.jar;C:\Users\Administrator\.m2\repository\jakarta\annotation\jakarta.annotation-api\1.3.5\jakarta.annotation-api-1.3.5.jar;C:\Users\Administrator\.m2\repository\org\yaml\snakeyaml\1.29\snakeyaml-1.29.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-aop\5.3.15\spring-aop-5.3.15.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-beans\5.3.15\spring-beans-5.3.15.jar;C:\Users\Administrator\.m2\repository\org\springframework\security\spring-security-config\5.6.1\spring-security-config-5.6.1.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-context\5.3.15\spring-context-5.3.15.jar;C:\Users\Administrator\.m2\repository\org\springframework\security\spring-security-web\5.6.1\spring-security-web-5.6.1.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-expression\5.3.15\spring-expression-5.3.15.jar;C:\Users\Administrator\.m2\repository\org\springframework\boot\spring-boot-starter-json\2.6.3\spring-boot-starter-json-2.6.3.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.13.1\jackson-databind-2.13.1.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.13.1\jackson-annotations-2.13.1.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.13.1\jackson-core-2.13.1.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.13.1\jackson-datatype-jdk8-2.13.1.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.13.1\jackson-datatype-jsr310-2.13.1.jar;C:\Users\Administrator\.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.13.1\jackson-module-parameter-names-2.13.1.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-web\5.3.15\spring-web-5.3.15.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-webmvc\5.3.15\spring-webmvc-5.3.15.jar;C:\Users\Administrator\.m2\repository\org\slf4j\slf4j-api\1.7.33\slf4j-api-1.7.33.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-core\5.3.15\spring-core-5.3.15.jar;C:\Users\Administrator\.m2\repository\org\springframework\spring-jcl\5.3.15\spring-jcl-5.3.15.jar;C:\Users\Administrator\.m2\repository\org\springframework\security\spring-security-core\5.6.1\spring-security-core-5.6.1.jar;C:\Users\Administrator\.m2\repository\org\springframework\security\spring-security-crypto\5.6.1\spring-security-crypto-5.6.1.jar" com.demo.springdemo.SpringDemoApplication . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.6.3) 2022-01-22 23:39:59.885 INFO 47256 --- [ main] c.c.springdemo.SpringDemoApplication : Starting SpringDemoApplication using Java 1.8.0_301 on 5YUOP71L7Z3I7K5 with PID 47256 (E:\code\example\java\spring-demo\target\classes started by Administrator in E:\code\example\java\spring-demo) 2022-01-22 23:39:59.887 INFO 47256 --- [ main] c.c.springdemo.SpringDemoApplication : No active profile set, falling back to default profiles: default 2022-01-22 23:40:00.295 INFO 47256 --- [ main] c.c.springdemo.SpringDemoApplication : Started SpringDemoApplication in 0.642 seconds (JVM running for 1.088) Process finished with exit code 0 I am sure the problem has something to do with spring boot version 2.6.2. Because when I change the version to 2.6.1 and below, everything is ok as usual. And version 2.6.3 doesn't work either. That's really an unexpected trap. Is there anyone who knows anything about it? ps:The code is as below: package com.demo.springdemo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; #RestController #SpringBootApplication public class SpringDemoApplication { #GetMapping("/") public String hello() { return "hello"; } public static void main(String[] args) { SpringApplication.run(SpringDemoApplication.class, args); } }
Please try after adding this dependency: <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency>
How to weave AspectJ java project into Spring boot project
I have java project named Test which have all aspects in it. I wan to use these aspects in another spring boot project. I am working on a poc to weave aspects in Test project into a spring boot application. What is the efficient way to do so and how it can be done, can some one who implemented please suggest. Code for Java project Test with aspects #Retention(RetentionPolicy.RUNTIME) #Target(ElementType.METHOD) public #interface Secured { public boolean isLocked() default false; } #Aspect public class SecuredMethodAspect { #Pointcut("#annotation(secured)") public void callAt(Secured secured) {} #Around("callAt(secured)") public Object around(ProceedingJoinPoint pjp, Secured secured) throws Throwable { if (secured.isLocked()) { System.out.println(pjp.getSignature().toLongString() + " is locked"); return pjp.proceed(); } else { return pjp.proceed(); } } } <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>aspect</groupId> <artifactId>test</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>AspectJ-POC</name> <url>http://maven.apache.org</url> <properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <java.version>11</java.version> </properties> <!-- nickwongdev aspectj maven plugin, this is for weaving of aspects --> <build> <plugins> <plugin> <groupId>com.nickwongdev</groupId> <artifactId>aspectj-maven-plugin</artifactId> <version>1.12.6</version> <configuration> <source>11</source> <target>11</target> <complianceLevel>11</complianceLevel> </configuration> <executions> <execution> <goals> <goal>compile</goal> <goal>test-compile</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <!-- aspectj runtime dependency --> <dependencies> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.9.6</version> </dependency> </dependencies> </project>
Some quick first impressions I got when browsing your projects before cloning them: You should not use Lombok + native AspectJ together in a compile-time weaving scenario, see my answer here. Possible workarounds would be multi-phase compilation, i.e. first Java + Lombok and then post-compile-time weaving with AspectJ, see my answer here. Alternatively, use delombok in order to first generate source code with Lombok annotations expanded into equivalent source code and then compile the generated sources with AspectJ. On a second look, your sample aspect module does not seem to use any Lombok, so you do not need that dependency. But probably your real project does, hence my remarks above. Of course, you can use compile-time weaving in order to weave your aspects, as you suggested. You need to correctly configure AspectJ Maven Plugin in this case, though, which you did not. You need to tell it in the Spring Boot module where to find the aspect library and which dependencies to weave, in addition to the main application. Did you ever read the plugin documentation, e.g. chapters Weaving classes in jars, Using aspect libraries and Multi-module use of AspectJ? I also answered tons of related questions here already. But actually, the preferred approach for weaving aspects into Spring applications is to use load-time weaving (LTW), as described in the Spring manual. That should be easier to configure and you would not need any AspectJ Maven Plugin stuff and probably would not have any Lombok issues during compilation either. Judging from your sample projects and the absence of any aspectLibraries and weaveDependencies sections in your AspectJ Maven configuration, you simply did not bother to read any documentation, which leaves me to wonder what you did during the one month you tried to get this working. I would appreaciate a comment, explaining why you want to use CTW instead of LTW. The only reason I can think of is that in addition to your native aspect, you also want to use Spring AOP aspects withing your Spring application. But if you activate native AspectJ LTW, you cannot use Spring AOP at the same time anymore. If that is not an issue, I recommend LTW, as it is documented and tested well in Spring. CTW is no problem either, but more difficult to understand and manage in your POMs. Update: OK, I did not want to wait any longer for your reason to use CTW and simply decided to show you a LTW solution instead. What I did was: Remove AspectJ Maven Plugin and AspectJ Tools from your Spring project Add src/main/resources/org/aspectj/aop.xml, configuring it to use your aspect and target your base package + subpackages Fix pointcut to also use your base package + subpackages, because in your base package there are no classes. This is a typical beginner's mistake. You need to use execution(* com.ak..*(..)) with .., not just com.ak.*. Non-essential cosmetics I applied are: Call context.getBean(TestController.class).mainRequest() from the Spring Boot application's main method in order to automatically produce some aspect output, in order to avoid having to use curl or a web browser in order to call a local URL. Use the Spring application as an auto-closeable via try-with-resources in order to make the application close after creating the desired log output. Change the aspect to also log the joinpoint in order to see in the log, which methods it actually intercepts. Otherwise all log lines look the same, which is not quite helpful. Use try-finally in order to make sure that the log message after proceeding to the original method is also logged in case of an exception. The diff looks like this (I hope you can read diffs): diff --git a/aspect-test-project/src/main/java/com/ak/aspect/MethodLogAspect.java b/aspect-test-project/src/main/java/com/ak/aspect/MethodLogAspect.java --- a/aspect-test-project/src/main/java/com/ak/aspect/MethodLogAspect.java (revision Staged) +++ b/aspect-test-project/src/main/java/com/ak/aspect/MethodLogAspect.java (date 1626233247623) ## -7,14 +7,14 ## #Aspect public class MethodLogAspect { - #Around("#annotation( MethodLog) && (execution(* com.ak.*(..)))") + #Around("#annotation(MethodLog) && execution(* com.ak..*(..))") public Object wrap(final ProceedingJoinPoint joinPoint) throws Throwable { - System.out.println("***Aspect invoked before calling method***"); - - final Object obj = joinPoint.proceed(); - - System.out.println("***Aspect invoked after calling method***"); - - return obj; + System.out.println("[BEFORE] " + joinPoint); + try { + return joinPoint.proceed(); + } + finally { + System.out.println("[AFTER] " + joinPoint); + } } } diff --git a/src/main/java/com/ak/ParentprojectSpringbootApplication.java b/src/main/java/com/ak/ParentprojectSpringbootApplication.java --- a/src/main/java/com/ak/ParentprojectSpringbootApplication.java (revision Staged) +++ b/src/main/java/com/ak/ParentprojectSpringbootApplication.java (date 1626233555873) ## -1,14 +1,17 ## package com.ak; +import com.ak.controller.TestController; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.context.ConfigurableApplicationContext; #SpringBootApplication(scanBasePackages = { "com.ak.*" }) -//#SpringBootApplication public class ParentprojectSpringbootApplication { public static void main(String[] args) { - SpringApplication.run(ParentprojectSpringbootApplication.class, args); + try (ConfigurableApplicationContext context = SpringApplication.run(ParentprojectSpringbootApplication.class, args)) { + context.getBean(TestController.class).mainRequest(); + } } } diff --git a/parentproject-springboot/pom.xml b/parentproject-springboot/pom.xml --- a/parentproject-springboot/pom.xml (revision Staged) +++ b/parentproject-springboot/pom.xml (date 1626232421474) ## -71,13 +71,6 ## <version>1.9.6</version> </dependency> - <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjtools --> - <dependency> - <groupId>org.aspectj</groupId> - <artifactId>aspectjtools</artifactId> - <version>1.9.6</version> - </dependency> - <dependency> <groupId>com.ak.aspect</groupId> <artifactId>aspect-test-project</artifactId> ## -100,24 +93,6 ## </configuration> </plugin> - <plugin> - <groupId>com.nickwongdev</groupId> - <artifactId>aspectj-maven-plugin</artifactId> - <version>1.12.6</version> - <configuration> - <source>11</source> - <target>11</target> - <complianceLevel>11</complianceLevel> - </configuration> - <executions> - <execution> - <goals> - <goal>compile</goal> - <goal>test-compile</goal> - </goals> - </execution> - </executions> - </plugin> </plugins> </build> For your convenience, here are the complete changed files: <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.5.2</version> <relativePath /> <!-- lookup parent from repository --> </parent> <groupId>com.ak</groupId> <artifactId>parentproject-springboot</artifactId> <version>0.0.1-SNAPSHOT</version> <name>parentproject-springboot</name> <description>Test project for Spring Boot</description> <properties> <java.version>11</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-rest</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.ak.dependency</groupId> <artifactId>dependencyprojet</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> <!-- aspectj runtime dependency --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.9.6</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.6</version> </dependency> <dependency> <groupId>com.ak.aspect</groupId> <artifactId>aspect-test-project</artifactId> <version>0.0.1-SNAPSHOT</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <excludes> <exclude> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </exclude> </excludes> </configuration> </plugin> </plugins> </build> </project> <!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd"> <aspectj> <weaver options="-verbose -showWeaveInfo"> <!-- only weave classes in our application-specific packages --> <include within="com.ak..*"/> </weaver> <aspects> <aspect name="com.ak.aspect.MethodLogAspect"/> </aspects> </aspectj> package com.ak.aspect; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; #Aspect public class MethodLogAspect { #Around("#annotation(MethodLog) && execution(* com.ak..*(..))") public Object wrap(final ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("[BEFORE] " + joinPoint); try { return joinPoint.proceed(); } finally { System.out.println("[AFTER] " + joinPoint); } } } package com.ak; import com.ak.controller.TestController; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; #SpringBootApplication(scanBasePackages = { "com.ak.*" }) public class ParentprojectSpringbootApplication { public static void main(String[] args) { try (ConfigurableApplicationContext context = SpringApplication.run(ParentprojectSpringbootApplication.class, args)) { context.getBean(TestController.class).mainRequest(); } } } Now you simply make sure to add the JVM argument -javaagent:/path/to/aspectjweaver-1.9.6.jar to your Java command line in order to activate native AspectJ LTW. For more details about how to configure LTW within Spring if more sophisticated ways, please read the Spring manual, section Using AspectJ with Spring Applications. The console log should look something like this: [AppClassLoader#3764951d] info AspectJ Weaver Version 1.9.6 built on Tuesday Jul 21, 2020 at 13:30:08 PDT [AppClassLoader#3764951d] info register classloader jdk.internal.loader.ClassLoaders$AppClassLoader#3764951d [AppClassLoader#3764951d] info using configuration /C:/Users/alexa/Documents/java-src/SO_AJ_SpringCTWMultiModule_68040124/parentproject-springboot/target/classes/org/aspectj/aop.xml [AppClassLoader#3764951d] info register aspect com.ak.aspect.MethodLogAspect [AppClassLoader#3764951d] warning javax.* types are not being woven because the weaver option '-Xset:weaveJavaxPackages=true' has not been specified [RestartClassLoader#1f385e10] info AspectJ Weaver Version 1.9.6 built on Tuesday Jul 21, 2020 at 13:30:08 PDT [RestartClassLoader#1f385e10] info register classloader org.springframework.boot.devtools.restart.classloader.RestartClassLoader#1f385e10 [RestartClassLoader#1f385e10] info using configuration /C:/Users/alexa/Documents/java-src/SO_AJ_SpringCTWMultiModule_68040124/parentproject-springboot/target/classes/org/aspectj/aop.xml [RestartClassLoader#1f385e10] info register aspect com.ak.aspect.MethodLogAspect . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.5.2) (...) [RestartClassLoader#1f385e10] weaveinfo Join point 'method-execution(com.ak.dependency.model.AccountInfo com.ak.service.TestService.incomingRequest())' in Type 'com.ak.service.TestService' (TestService.java:20) advised by around advice from 'com.ak.aspect.MethodLogAspect' (MethodLogAspect.java) [RestartClassLoader#1f385e10] weaveinfo Join point 'method-execution(com.ak.dependency.model.AccountInfo com.ak.dependency.Route.accountInfo())' in Type 'com.ak.dependency.Route' (Route.java:12) advised by around advice from 'com.ak.aspect.MethodLogAspect' (MethodLogAspect.java) [RestartClassLoader#1f385e10] weaveinfo Join point 'method-execution(com.ak.dependency.model.BalanceInfo com.ak.dependency.Pipeline.balanceInfo())' in Type 'com.ak.dependency.Pipeline' (Pipeline.java:11) advised by around advice from 'com.ak.aspect.MethodLogAspect' (MethodLogAspect.java) (...) Controller [BEFORE] execution(AccountInfo com.ak.service.TestService.incomingRequest()) [BEFORE] execution(AccountInfo com.ak.dependency.Route.accountInfo()) [BEFORE] execution(BalanceInfo com.ak.dependency.Pipeline.balanceInfo()) [AFTER] execution(BalanceInfo com.ak.dependency.Pipeline.balanceInfo()) [AFTER] execution(AccountInfo com.ak.dependency.Route.accountInfo()) [AFTER] execution(AccountInfo com.ak.service.TestService.incomingRequest()) (...)
Adding a JNI library to a spring boot (maven) jar
I'm using Google Or-Tools library over a Java-Spring-Boot app, Windows 10 OS and Intellij IDE. To make it work over intellij I did the following: Install Microsoft Visual C++ Redistributable for Visual Studio 2019 (required according to the installation instructions). Downloaded and extracted the OR-Tools library for Java (included 2 jars and a 1 dll file). In Intellij, I added those jars as module dependencies (under a folder called lib). Added the lib library path to VM options in Intellij run configurations. Loaded the library statically in my code: static {System.loadLibrary("jniortools");} Now I can run the project successfully form Intellij. Next I would like to pack everything to a spring boot jar that can run over any windows machine. My folders structure is: My pom file is pretty basic, a few dependencies with a standard spring-boot-maven-plugin: <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> As I'm trying to pack the code using mvn install I'm getting package com.google.ortools.sat does not exist. How can I make sure maven packs those 3rd party jars to the executable spring-boot jar? UPDATE I added to my pom file: <dependency> <groupId>com.google.ortools</groupId> <artifactId>ortools</artifactId> <version>LATEST</version> <type>jar</type> <scope>system</scope> <systemPath>${project.basedir}/lib/com.google.ortools.jar</systemPath> </dependency> <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>LATEST</version> <type>jar</type> <scope>system</scope> <systemPath>${project.basedir}/lib/protobuf.jar</systemPath> </dependency> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.7</version> <executions> <execution> <phase>generate-test-sources</phase> <configuration> <tasks> <mkdir dir="${project.basedir}/target/lib"/> <echo message="Creating lib folder..."/> <copy todir="${project.basedir}/target/lib"> <fileset dir="${project.basedir}/lib"> <include name="**/**"/> </fileset> </copy> </tasks> </configuration> <goals> <goal>run</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> In addition adding to library path: static { try { String orToolsDllLibrary = System.getProperty("user.dir") + "\\lib"; addLibraryPath(orToolsDllLibrary); System.loadLibrary("jniortools"); } catch (Exception e) { e.printStackTrace(); } } public static void addLibraryPath(String pathToAdd) throws Exception { final Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths"); usrPathsField.setAccessible(true); //get array of paths final String[] paths = (String[]) usrPathsField.get(null); //check if the path to add is already present for (String path : paths) { if (path.equals(pathToAdd)) { return; } } //add the new path final String[] newPaths = Arrays.copyOf(paths, paths.length + 1); newPaths[newPaths.length - 1] = pathToAdd; usrPathsField.set(null, newPaths); } And now when running command java -jar myApp-0.0.1-SNAPSHOT.jar getting an exception: Caused by: java.lang.NoClassDefFoundError: com/google/ortools/sat/CpSolver at java.base/java.lang.Class.getDeclaredMethods0(Native Method) ~[na:na] at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3167) ~[na:na] at java.base/java.lang.Class.getDeclaredMethods(Class.java:2310) ~[na:na] at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:463) ~[spring-core-5.2.6.RELEASE.jar!/:5.2.6.RELEASE] ... 29 common frames omitted Caused by: java.lang.ClassNotFoundException: com.google.ortools.sat.CpSolver at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471) ~[na:na] at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588) ~[na:na] at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:129) ~[solver-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT] at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521) ~[na:na] ... 33 common frames omitted
I am not sure how you added the library to your project? You don't seem to have done it through Maven, did you? In the past I took the approach of adding it via using system scope in Maven (see here. This would give you something like this in your pom: <dependency> <groupId>com.google.ortools</groupId> <artifactId>ortools</artifactId> <version>1.0</version> <scope>system</scope> <systemPath>${basedir}/src/main/resources/lib/com.google.ortools.jar</systemPath> </dependency> However, this approach can also be a pain especially if you have to work multi-platform. Recently, I found this repo and that made my life much easier dealing with OR-tools. Hope this helps. UPDATE: I strongly recommend using the updated method below as it is much less of a headache: <repositories> ... <repository> <id>bintray</id> <url>https://dl.bintray.com/magneticflux/maven</url> </repository> .... </repositories> <dependencies> <dependency> <groupId>com.skaggsm.ortools</groupId> <artifactId>ortools-natives-all</artifactId> <version>7.7.7810</version> </dependency> <!-- OR-tools needs protobuf --> <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>3.12.2</version> </dependency> </dependencies> Then you can do a static load of the library: static { OrToolsHelper.loadLibrary() } Make sure to work with JDK >= 11 as elaborated here.
I tried: First add the jniortools library to java.library.path pragmatically: static { String orToolsDllLibrary = System.getProperty("user.dir") + "\\lib"; addLibraryPath(orToolsDllLibrary); System.loadLibrary("jniortools"); } public static void addLibraryPath(String pathToAdd) throws Exception { final Field usrPathsField = ClassLoader.class.getDeclaredField("usr_paths"); usrPathsField.setAccessible(true); //get array of paths final String[] paths = (String[]) usrPathsField.get(null); //check if the path to add is already present for (String path : paths) { if (path.equals(pathToAdd)) { return; } } //add the new path final String[] newPaths = Arrays.copyOf(paths, paths.length + 1); newPaths[newPaths.length - 1] = pathToAdd; usrPathsField.set(null, newPaths); } In pom file: <dependencies> .... <dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> <version>3.12.2</version> </dependency> <dependency> <groupId>com.google</groupId> <artifactId>ortools</artifactId> <version>0.0.2</version> </dependency> .... </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-install-plugin</artifactId> <version>2.5.2</version> <executions> <execution> <id>install-external</id> <phase>process-resources</phase> <configuration> <file>${basedir}/lib/com.google.ortools.jar</file> <repositoryLayout>default</repositoryLayout> <groupId>com.google</groupId> <artifactId>ortools</artifactId> <version>0.0.2</version> <packaging>jar</packaging> <generatePom>true</generatePom> </configuration> <goals> <goal>install-file</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-antrun-plugin</artifactId> <version>1.7</version> <executions> <execution> <phase>generate-sources</phase> <configuration> <tasks> <mkdir dir="${project.basedir}/target/lib"/> <echo message="Creating lib folder..."/> <copy todir="${project.basedir}/target/lib"> <fileset dir="${project.basedir}/lib"> <include name="**/**"/> </fileset> </copy> </tasks> </configuration> <goals> <goal>run</goal> </goals> </execution> </executions> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
Spring Maven Project - java.lang.IllegalArgumentException: Sources must not be empty
I am trying to start up a Spring Boot application but it is failing to start up. This is my stack trace: 11:27:59.772 [main] DEBUG org.springframework.boot.devtools.settings.DevToolsSettings - Included patterns for restart : [] 11:27:59.775 [main] DEBUG org.springframework.boot.devtools.settings.DevToolsSettings - Excluded patterns for restart : [/spring-boot-starter/target/classes/, /spring- boot-autoconfigure/target/classes/, /spring-boot-starter-[\w-]+/, /spring-boot/target/classes/, /spring-boot-actuator/target/classes/, /spring-boot-devtools/target/classes/] 11:27:59.776 [main] DEBUG org.springframework.boot.devtools.restart.ChangeableUrls - Matching URLs for reloading : [file:/C:/Users/Bobi/Documents/workspace-sts- 3.9.2.RELEASE/springproject/target/classes/] . ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.0.0.M7) 2018-03-18 11:28:00.308 INFO 5048 --- [ restartedMain] o.s.boot.SpringApplication : Starting SpringApplication v2.0.0.M7 on DESKTOP-MFS6ORP with PID 5048 (C:\Users\Bobi\.m2\repository\org\springframework\boot\spring- boot\2.0.0.M7\spring-boot-2.0.0.M7.jar started by Bobi in C:\Users\Bobi\Documents\workspace-sts-3.9.2.RELEASE\springproject) 2018-03-18 11:28:00.313 INFO 5048 --- [ restartedMain] o.s.boot.SpringApplication : No active profile set, falling back to default profiles: default 2018-03-18 11:28:01.410 ERROR 5048 --- [ restartedMain] o.s.boot.SpringApplication : Application startup failed java.lang.IllegalArgumentException: Sources must not be empty at org.springframework.util.Assert.notEmpty(Assert.java:450) ~[spring- core-5.0.2.RELEASE.jar:5.0.2.RELEASE] at org.springframework.boot.SpringApplication.prepareContext(SpringApplication.java:381) [spring-boot-2.0.0.M7.jar:2.0.0.M7] at org.springframework.boot.SpringApplication.run(SpringApplication.java:325) [spring-boot-2.0.0.M7.jar:2.0.0.M7] at org.springframework.boot.SpringApplication.run(SpringApplication.java:1245) [spring-boot-2.0.0.M7.jar:2.0.0.M7] at org.springframework.boot.SpringApplication.main(SpringApplication.java:1261) [spring-boot-2.0.0.M7.jar:2.0.0.M7] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_151] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_151] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_151] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_151] at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher .java:49) [spring-boot-devtools-2.0.0.M7.jar:2.0.0.M7] This is my main class: package com.example.a; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; #SpringBootApplication public class App { public static void main( String[] args ) { SpringApplication.run(App.class, args); } } This is my 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>com.example</groupId> <artifactId>a</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>a</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> I am using Spring Tool Suite and I created the project by File->New->Maven Project. I added some dependencies and added the SpringApplication.run(App.class, args); row in the main class and that's it. I tried other similar suggestions on StackOverflow but nothing worked for me. What do I have to do or change in order to get the application to start up correctly?
I solved the problem. I don't know how I was running the project before, but I just went Right Click->Run As->Spring Boot App and it worked properly.
In Eclipse, when I was running it as a spring boot app, it showed the error, but when I ran it as Java Application from Right-click-> run as -> Java Application, it worked completely fine.
maven plugin descriptor not getting generated
I'm creating a maven plugin, MVN clean install build succeeds but plugin.xml is not getting generated. #Mojo( name = "cover", defaultPhase = LifecyclePhase.POST_INTEGRATION_TEST) public class RunCoverage extends AbstractMojo { #Parameter( property = "cover.wadl", defaultValue = "test") private String wadl; #Parameter( property = "cover.endpoints",defaultValue = "test") private String endpoints; #Override public void execute() throws MojoExecutionException { <somecode> } } And the pom.xml is <?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> <artifactId>end-point-test-coverage</artifactId> <version>1</version> <dependencies> <dependency> <groupId>org.apache.maven</groupId> <artifactId>maven-plugin-api</artifactId> <version>2.0</version> </dependency> <dependency> <groupId>org.apache.maven.plugin-tools</groupId> <artifactId>maven-plugin-annotations</artifactId> <version>3.2</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-plugin-plugin</artifactId> <version>3.2</version> <executions> <execution> <id>default-descriptor</id> <goals> <goal>descriptor</goal> </goals> <phase>process-classes</phase> </execution> <execution> <id>help-descriptor</id> <goals> <goal>helpmojo</goal> </goals> <phase>process-classes</phase> </execution> </executions> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.0.2</version> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build> </project> Maven clean install doesn't generate plugin.xml When used in a dependent project, I'm getting the following error Failed to parse plugin descriptor for it.gruppopam.common:end-point-test-coverage:1 (/home/d/.m2/repository/it/common/end-point-test-coverage/1/end-point-test-coverage-1.jar): No plugin descriptor found at META-INF/maven/plugin.xml -> [Help 1] [ERROR]
First i would try to set the packaging type to maven-plugin instead of the default which is jar. Furthermore i would suggest to use more up-to-date versions of plugins (maven-compiler-plugin: 3.1) and use a more up-to-date version of maven-plugin-api (3.0? but not 2.0).
you have to remember to change it in your pom.xml to: <packaging>maven-plugin</packaging> it is by default: <packaging>jar</packaging>