How do I create a distributable application in Clojure? - java

What is the 'least work' approach to distributing a Clojure application? And is this different from the 'best' approach?
For example here is a trivial 'application' that I want to be able to send to someone:
(doto (javax.swing.JFrame. "Hello World")
(.add (javax.swing.JLabel. "Clojure Distributable"))
(.pack)
(.show))
I imagine it makes a big difference to the answer whether they have Java installed already or not.

For Mac Os x, java is installed by default and apple provides JarBundler that allows you to turn jars in to native os x applications. OS X applications don't use installers.
For Windows Launch4j is a good choice it will wrap your jar into .exe with an icon also it will check if java is installed if not download it. For a windows installer i recommend NSIS (winamp's installer).
For Linux, jar file + bash script.

Compile it to byte code and then use Java Web Start (or what every Java installer floats your boat)?
For people without Java installed - Some installed can detect this and fire off the JRE installer. The web JWS does this is some Javascript on the page with the link to the JNLP file. This then will switch the link out for a JRE install link if Java is not detected.

The easiest way would be to use Maven, here's what you'll need to do:
Get a copy of Maven 2 installed.
get a copy of the Clojure Maven Plugin, go to its folder and run mvn install
Install clojure.jar into your maven repository by running the following command:
mvn install:install-file -DgroupId=org.clojure -DartifactId=clojure -Dversion=1.1.0-alpha-SNAPSHOT -Dpackaging=jar
-Dfile=clojure.jar
Now you'll need to create a pom.xml which will tell maven how to build your project
<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>org.clojure</groupId>
<artifactId>hello-world</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<build>
<plugins>
<plugin>
<groupId>com.theoryinpractise</groupId>
<artifactId>clojure-maven-plugin</artifactId>
<version>1.1-SNAPSHOT</version>
<configuration>
<sourceDirectories>
<sourceDirectory>src</sourceDirectory>
</sourceDirectories>
</configuration>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.clojure</groupId>
<artifactId>clojure</artifactId>
<version>1.1.0-alpha-SNAPSHOT</version>
</dependency>
</dependencies>
</project>
So now, say you have a hello.clj that look like:
(ns clojure.examples.hello
(:gen-class))
(defn -main[args]
(doto (javax.swing.JFrame. "Hello World")
(.add (javax.swing.JLabel. "Clojure Distributable"))
(.pack)
(.show)))
your project structure should look like:
project/pom.xml
project/src/clojure/examples/hello.clj
if you go to the project folder and run mvn install, it should create project/target/hello-world-1.0.jar which will have a main method, you should be able to run it with
java -cp hello-world-1.0.jar:clojure.jar clojure.examples.hello
You might also want to look into One-Jar project, which would let you bundle both your application and the clojure library in the same jar.

Consider Excelsior JET, if you need totally stand-alone app.
Consider some jar-to-exe wrappers, like launch4j.
These advices are for Java platform generally, rather then specifically for Clojure...

Related

Adding Javalin dependencies

I'm trying to use Javalin in my project and I can't seem to understand how to add the needed dependencies in order to work with Javalin without compliation errors.
The project i'm working on is not a Maven project, it is a simple Java project so it won't be downloaded automatically.
How do I add the dependencies and where?
I am using VSCode but can Switch to Intellij IDEA if needed.
Thanks.
At the risk of pointing you in a direction you may not want to go in... Use a dependency manager (Maven, Gradle, Ivy, or similar). Simple Java projects can be dependency-managed projects, too!
A basic Javalin project includes dozens of dependencies - and dependencies of those dependencies... You will probably have an unpleasant time attempting to handle them all manually, one-by-one.
If you use the Javalin bundle, that will take care of all of this for you.
To give you a sense of what I mean:
If you do decide to use a dependency manager, then your follow-up questions are well covered elsewhere. Or you can ask a follow-up, based on any problems you may encounter.
Update
Yeah but were doing it in a school project and were already half way through the project and now I need to add a Web Client and we don't want to change things all through the project, there's gotta be a way to add those dependencies without creating a new Maven project for it.
You can install Maven and run a command to download all the JARs to a directory.
This is (in my opinion) more work than just using Maven already built into all mainstream IDEs, but here are the steps:
Note: My set-up assumes Windows. You can adjust as needed for Linux or a different OS.
Download Maven - see here.
I downloaded the binary zip archive.
Set up Maven - see here.
Be sure to pay particular attention to the instructions regarding setting the JAVA_HOME environment variable pointing to your JDK installation or having the java executable on your PATH.
I installed my Maven here:
C:\maven\apache-maven-3.8.5
I tested it in a shell using the mvn -v command:
C:\maven\apache-maven-3.8.5\bin\mvn -v
Create a pom.xml file. Maven uses this as its instructions for what to download (and to what location).
In my case I created the POM here:
C:\maven\demo\pom.xml
Its contents are:
<?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>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
</properties>
<groupId>org.andrewjames</groupId>
<artifactId>my-Javalin-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>io.javalin</groupId>
<artifactId>javalin-bundle</artifactId>
<version>4.5.0</version>
</dependency>
</dependencies>
<build>
<finalName>my-Javalin-demo</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.3.0</version>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<silent>true</silent>
<outputDirectory>C:/maven/demo</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<name>my-Javalin-demo</name>
</project>
The maven.compiler sections assume I have Java 17 available. You may need to adjust to match your Java version.
The dependencies section is where the javalin-bundle is defined.
The execution section is the directive which causes all dependency JARs to be downloaded to the Maven local repository, and then copied to a new directory.
In my case the new directory will be created here:
C:\maven\demo\target\dependency
Open a CMD shell and cd to C:\maven\demo
At the command line, run the following command:
C:\maven\apache-maven-3.8.5\bin\mvn dependency:copy-dependencies
After that has completed, you will see approx. 100 JAR files in the C:\maven\demo\target\dependency directory.

Launch JavaFX application configured with Maven from Eclipse

I have a JavaFX application that properly runs with Maven:
mvn compile
mvn exec:java # Launches the GUI
This is on Ubuntu, using openjdk-11-jdk, maven and openjfx Ubuntu packages.
I want to compile and run this application from the Eclipse IDE (eclipse installed with sudo snap install --classic eclipse). I have the m2e (Maven to Eclipse) plugin installed, and imported the project with File -> Import -> Maven -> Existing Maven Project. For non-JavaFX projects, the m2e plugin does everything needed to configure the project in Eclipse from Maven's pom.xml. Unfortunately, in my case, something is missing: typechecking works properly and finds the javafx.* classes, but when I try to run the application, I get the following error message in the console:
Error: JavaFX runtime components are missing, and are required to run this application
A workaround is to run the application as a Maven application (Run -> Run As -> Maven Build -> target=exec:java), but I find it less convenient and slower, so I'm looking for a way to get the application to run directly as a Java application in Eclipse.
I found the way to configure Eclipse manually (posted below as an answer), but I'm still wondering whether there's a better way, that would let Maven + m2e do the job completely, i.e. as much as possible configure everything from pom.xml and have everything "just work" in Eclipse.
The problem can be reproduced on a minimalist example, with this 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>jfxpl</groupId>
<artifactId>jfxpl</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11.0.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.2</version>
<configuration>
<mainClass>App</mainClass>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.5.0</version>
<configuration>
<mainClass>App</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
And any application using JavaFX like:
import javafx.application.Application;
import javafx.stage.Stage;
public class App extends Application {
#Override
public void start(Stage stage) throws Exception {
System.out.println("Start!"); // Or real JavaFX stuff here obviously
}
public static void main(String[] args) {
Application.launch(args);
}
}
Since you have a Maven project, you could simply use the goals from the maven plugin you are using, and get Eclipse (via m2e) to run this for you, but you have to specify which are these goals, and which configuration you want to run.
Let's say you have this HelloFX sample.
Your pom will look like:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>12</release>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.3</version>
<configuration>
<mainClass>org.openjfx.hellofx.App</mainClass>
</configuration>
</plugin>
</plugins>
</build>
Note that I'm using the javafx-maven-plugin instead of the exec-maven-plugin, but you could use it as well. The former properly takes care of adding the JavaFX modules to the modular path, while the latter doesn't use modules at all.
If you were on a terminal, setting JDK 12 and running:
mvn clean javafx:run
will work as expected.
However, you want to run this from Eclipse, and not from a terminal, so you can create a new Maven Build configuration from Run -> Run Configurations... -> Maven Build:
Add clean javafx:run, and make sure the JRE is properly set (JDK 12 for instance). Press apply and close the dialog.
Now you can click the Run as green icon from the toolbar or from the context menu. A dialog will show up, and you could simply select the Maven Build option:
and press OK, it will run your goals as expected.
If you didn't have any Run configuration created, when selecting Maven Build will ask you to create one and provide the required goals. This means that Eclipse doesn't guess which of the possible goals from your pom you want to run when you click the run button.
Note that alternatively, you can press the drop down icon, and open a dialog that will show your custom configurations:
Pressing hellofx will run the specified goals.
Finally, you can still run your project as Java Application, without the benefits of a build tool like Maven, and you will have to add the VM arguments (which means you need to download the JavaFX SDK in the first place), as in your answer. Then you could run this other configuration (hellofx2 in my case) from the same drop down button.
Note that all of this is documented in detail here.
OpenJDK for linux doesnt come with the JAVAFX framework. you need to download it and install.
sudo apt-get install openjfx
After installing use following steps:
Set the SDK first
Step 1:
GOTO File -> Project Structure -> Modules -> Dependency >> + [on left-side of window] click + sign
Step 2 :
Run >> Edit Configurations
Step3: Add below parameter in VM config :
--module-path /path/to/JavaFX/lib --add-modules=javafx.controls
One solution is to configure Eclipse manually to add the required modules: Run -> Run configurations -> Java Application -> Arguments -> VM Arguments, add --module-path /path/to/JavaFX/lib --add-modules=javafx.controls:
If you need other modules, specify then as a comma-separated list like --add-modules javafx.controls,javafx.fxml.
This might be duplicate, did you try this
<plugin>
<groupId>com.zenjava</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>8.8.3</version>
<configuration>
<mainClass>your.main.class.which.extends.javafx.Application</mainClass>
</configuration>
</plugin>
Provided here: JavaFX Application with Maven in Eclipse
Also, there are docs for it, which probably correlate exactly to Java 11.
https://openjfx.io/openjfx-docs/
Here are the OpenJFX releases, provided from the docs.
https://gluonhq.com/products/javafx/
Also,
https://openjfx.io/openjfx-docs/images/ide/eclipse/modular/maven/eclipse05.png
Is a great image of the build through maven.

JavaFX and Maven in Intellij: JAVA_HOME set but "Unrecognized option --module-path" error persisting

Using Maven and JavaFX in Intellij (2019.1). I have been following this tutorial.
I have a curious error that keeps occurring - every time I keep running the javafx:run plugin, it fails, giving this error:
Error: Could not create the Java Virtual Machine.
Error: A fatal exception has occurred. Program will exit.
Unrecognized option: --module-path
However, when I put the executable in the javafx-maven-plugin (<executable>"C:\Program Files\Java\jdk-12.0.1\bin\java.exe"</executable>) it works. I am on Windows and have set the JAVA_HOME system environment variable to C:\Program Files\Java\jdk-12.0.1 which is where the JDK is installed.
This is a curious issue that is not critical, but would be nice to know the answer to.
EDIT:
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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>uk.co.harveyellis</groupId>
<artifactId>HelloFX</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>12</maven.compiler.source>
<maven.compiler.target>12</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>11.0.2</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>11.0.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.0</version>
<configuration>
<release>12</release>
</configuration>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.2</version>
<configuration>
<mainClass>uk.co.harveyellis.App</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
Other pictures:
Environment Path
C:\Rtools\bin
C:\Program Files\Microsoft MPI\Bin\
C:\Python37\Scripts\
C:\Python37\
C:\WINDOWS\system32
C:\WINDOWS
C:\WINDOWS\System32\Wbem
C:\WINDOWS\System32\WindowsPowerShell\v1.0\
C:\WINDOWS\System32\OpenSSH\
C:\Program Files\Java\jdk-12.0.1\bin
C:\Program Files\apache-maven-3.6.1\bin
C:\Program Files (x86)\Common Files\Oracle\Java\javapath
C:\ProgramData\chocolatey\bin
C:\Program Files (x86)\Brackets\command
C:\Program Files\Git\cmd
C:\Program Files\dotnet\
C:\Program Files\Microsoft SQL Server\130\Tools\Binn\
C:\Program Files\PuTTY\
C:\Program Files\nodejs\
C:\Program Files\Gradle\gradle-5.4\bin
Note also that C:\Program Files\JetBrains\IntelliJ IDEA 2019.1.1\bin is in user path.
For future viewers, the answer turned out to be very simple: the instructions for maven at the getting started with JavaFX are with intellij and maven (non-module version), as found here are slightly incorrect.
The instructions are as follows:
You can open the Maven Projects window and click on HelloFX -> Plugins -> compiler -> compiler:compile to compile the project, and click on HelloFX -> Plugins -> javafx -> javafx:run to execute the project.
The key part that is wrong here is that if you are using a project that uses static resources - like the FXML files in the HelloFX project - then compiling only using compiler:compile will not copy these files into the target\classes directory.
This is a subtle mistake in the guide - presumably because if you build from command line nothing will be wrong - using mvn clean javafx:run will perform all the steps in between. Therefore, the instructions need to be to run compiler:compile and resources:resources for the thing to work in Intellij.
Alternatively, the guide could be changed to say just run javafx:compile or run the lifecycle phase called package in intellij, and then run javafx:run.
I've been experiencing similar pains with setting up a JavaFX project with Maven. That command requires a newer version of the JDK and the issue at hand is that Maven will actually ignore your system's JAVA_HOME and JDK_HOME variables, as well as your IDE settings.
You can check which version of Java that Maven is using by simply executing this command in your console:
$ java -version
In the case of Windows, you just move the entry pointing to the newer Java version above the older one, like so:
To see if you have JAVA_HOME set open cmd prompt:
echo %JAVA_HOME%
If nothing prints on the console, you need to set that variable, even if is already on the PATH variable, those are two different environment variables.

Java compilation problem -- default methods not allowed [duplicate]

I imported a Maven project and it used Java 1.5 even though I have 1.6 configured as my Eclipse default Preferences->Java->Installed JREs.
When I changed the Maven project to use the 1.6 JRE it still had the build errors left over from when the project was using Java 1.5 (I described these build errors earlier in: I have build errors with m2eclipse but not with maven2 on the command line - is my m2eclipse misconfigured?)
I'm going to delete the project and try again but I want to make sure this time that it uses Java 1.6 from the start to see if this eliminates the build problems.
How do I make sure the project uses Java 1.6 when I import it?
The m2eclipse plugin doesn't use Eclipse defaults, the m2eclipse plugin derives the settings from the POM. So if you want a Maven project to be configured to use Java 1.6 settings when imported under Eclipse, configure the maven-compiler-plugin appropriately, as I already suggested:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
If your project is already imported, update the project configuration (right-click on the project then Maven V Update Project Configuration).
I added this to my pom.xml below the project description and it worked:
<properties>
<maven.compiler.source>1.6</maven.compiler.source>
<maven.compiler.target>1.6</maven.compiler.target>
</properties>
I wanted to add something to the answer already provided. maven-compiler-plugin by default will compile your project using Java 1.5 which is where m2e get's its information.
That's why you have to explicitly declare the maven-compiler-plugin in your project with something other then 1.5. Your effective pom.xml will implicitly use the default set in the maven-compiler-plugin pom.xml.
<project>
<!-- ... -->
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.2</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
Your JRE was probably defined in run configuration. Follow these steps in Eclipse to change the build JRE.
1) Right click on the project and select Run As > Run Configurations
2) From Run Configurations window, select your project build configuration on the left panel. On the right, you will see various tabs: Main, JRE, Refresh, Source,...
3) Click on JRE tab, you should see something like this
4) By default, Work Default JRE (The JRE you select as default under Preferences->Java->Installed JREs) will be used. If you want to use another installed JRE, tick the Alternate JRE checkbox and select your preferred JRE from the dropdown.
Here is the root cause of java 1.5:
Also note that at present the default source setting is 1.5 and the default target setting is 1.5, independently of the JDK you run Maven with. If you want to change these defaults, you should set source and target.
Reference : Apache Mavem Compiler Plugin
Following are the details:
Plain 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.pluralsight</groupId>
<artifactId>spring_sample</artifactId>
<version>1.0-SNAPSHOT</version>
</project>
Following plugin is taken from an expanded POM version(Effective POM),
This can be get by this command from the command line C:\mvn help:effective-pom I just put here a small snippet instead of an entire pom.
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<executions>
<execution>
<id>default-compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>default-testCompile</id>
<phase>test-compile</phase>
<goals>
<goal>testCompile</goal>
</goals>
</execution>
</executions>
</plugin>
Even here you don't see where is the java version defined, lets dig more...
Download the plugin, Apache Maven Compiler Plugin ยป 3.1 as its available in jar and open it in any file compression tool like 7-zip
Traverse the jar and findout
plugin.xml
file inside folder
maven-compiler-plugin-3.1.jar\META-INF\maven\
Now you will see the following section in the file,
<configuration>
<basedir implementation="java.io.File" default-value="${basedir}"/>
<buildDirectory implementation="java.io.File" default-value="${project.build.directory}"/>
<classpathElements implementation="java.util.List" default-value="${project.testClasspathElements}"/>
<compileSourceRoots implementation="java.util.List" default-value="${project.testCompileSourceRoots}"/>
<compilerId implementation="java.lang.String" default-value="javac">${maven.compiler.compilerId}</compilerId>
<compilerReuseStrategy implementation="java.lang.String" default-value="${reuseCreated}">${maven.compiler.compilerReuseStrategy}</compilerReuseStrategy>
<compilerVersion implementation="java.lang.String">${maven.compiler.compilerVersion}</compilerVersion>
<debug implementation="boolean" default-value="true">${maven.compiler.debug}</debug>
<debuglevel implementation="java.lang.String">${maven.compiler.debuglevel}</debuglevel>
<encoding implementation="java.lang.String" default-value="${project.build.sourceEncoding}">${encoding}</encoding>
<executable implementation="java.lang.String">${maven.compiler.executable}</executable>
<failOnError implementation="boolean" default-value="true">${maven.compiler.failOnError}</failOnError>
<forceJavacCompilerUse implementation="boolean" default-value="false">${maven.compiler.forceJavacCompilerUse}</forceJavacCompilerUse>
<fork implementation="boolean" default-value="false">${maven.compiler.fork}</fork>
<generatedTestSourcesDirectory implementation="java.io.File" default-value="${project.build.directory}/generated-test-sources/test-annotations"/>
<maxmem implementation="java.lang.String">${maven.compiler.maxmem}</maxmem>
<meminitial implementation="java.lang.String">${maven.compiler.meminitial}</meminitial>
<mojoExecution implementation="org.apache.maven.plugin.MojoExecution">${mojoExecution}</mojoExecution>
<optimize implementation="boolean" default-value="false">${maven.compiler.optimize}</optimize>
<outputDirectory implementation="java.io.File" default-value="${project.build.testOutputDirectory}"/>
<showDeprecation implementation="boolean" default-value="false">${maven.compiler.showDeprecation}</showDeprecation>
<showWarnings implementation="boolean" default-value="false">${maven.compiler.showWarnings}</showWarnings>
<skip implementation="boolean">${maven.test.skip}</skip>
<skipMultiThreadWarning implementation="boolean" default-value="false">${maven.compiler.skipMultiThreadWarning}</skipMultiThreadWarning>
<source implementation="java.lang.String" default-value="1.5">${maven.compiler.source}</source>
<staleMillis implementation="int" default-value="0">${lastModGranularityMs}</staleMillis>
<target implementation="java.lang.String" default-value="1.5">${maven.compiler.target}</target>
<testSource implementation="java.lang.String">${maven.compiler.testSource}</testSource>
<testTarget implementation="java.lang.String">${maven.compiler.testTarget}</testTarget>
<useIncrementalCompilation implementation="boolean" default-value="true">${maven.compiler.useIncrementalCompilation}</useIncrementalCompilation>
<verbose implementation="boolean" default-value="false">${maven.compiler.verbose}</verbose>
<mavenSession implementation="org.apache.maven.execution.MavenSession" default-value="${session}"/>
<session implementation="org.apache.maven.execution.MavenSession" default-value="${session}"/>
</configuration>
Look at the above code and find out the following 2 lines
<source implementation="java.lang.String" default-value="1.5">${maven.compiler.source}</source>
<target implementation="java.lang.String" default-value="1.5">${maven.compiler.target}</target>
Good luck.
Simplest solution in Springboot
I'll give you the simplest one if you use Springboot:
<properties>
<java.version>1.8</java.version>
</properties>
Then, right click on your Eclipse project: Maven > Update project > Update project configuration from pom.xml
That should do.
One more possible reason if you are using Tycho and Maven to build bundles, that you have wrong execution environment (Bundle-RequiredExecutionEnvironment) in the manifest file (manifest.mf) defined. For example:
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Engine Plug-in
Bundle-SymbolicName: com.foo.bar
Bundle-Version: 4.6.5.qualifier
Bundle-Activator: com.foo.bar.Activator
Bundle-Vendor: Foobar Technologies Ltd.
Require-Bundle: org.eclipse.core.runtime,
org.jdom;bundle-version="1.0.0",
org.apache.commons.codec;bundle-version="1.3.0",
bcprov-ext;bundle-version="1.47.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.5
Export-Package: ...
...
Import-Package: ...
...
In my case everything else was ok. The compiler plugins (normal maven and tycho as well) were set correctly, still m2 generated old compliance level because of the manifest. I thought I share the experience.
Project specific settings
One more place where this can go wrong is in the project specific settings, in Eclipse.
project properties: click your project and one of the following:
Alt + Enter
Menu > Project > Properties
right click your project > project properties (last item in the menu)
click on "Java Compiler"
Uncheck "Enable project specific settings" (or change them all by hand).
Because of client requirements we had them enabled to keep our projects in 1.6. When it was needed to upgrade to 1.7, we had a hard time because we needed to change the java version all over the place:
project POM
Eclipse Workspace default
project specific settings
executing virtual machine (1.6 was used for everything)
In case anyone's wondering why Eclipse still puts a J2SE-1.5 library on the Java Build Path in a Maven project even if a Java version >= 9 is specified by the maven.compiler.release property (as of October 2020, that is Eclipse version 2020-09 including Maven version 3.6.3): Maven by default uses version 3.1 of the Maven compiler plugin, while the release property has been introduced only in version 3.6.
So don't forget to include a current version of the Maven compiler plugin in your pom.xml when using the release property:
<properties>
<maven.compiler.release>15</maven.compiler.release>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
</plugins>
</build>
Or alternatively but possibly less prominent, specify the Java version directly in the plugin configuration:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>15</release>
</configuration>
</plugin>
</plugins>
</build>
This picks up Line's comment on the accepted answer which, had I seen it earlier, would have saved me another hour of searching.
I found that my issue was someone committed the file .project and .classpath that had references to Java1.5 as the default JRE.
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5">
<attributes>
<attribute name="owner.project.facets" value="java"/>
</attributes>
</classpathentry>
By closing the project, removing the files, and then re-importing as a Maven project, I was able to properly set the project to use workspace JRE or the relevant jdk without it reverting back to 1.5 . Thus, avoid checking into your SVN the .project and .classpath files
Hope this helps others.
If you want to make sure that newly created projects or imported projects in Eclipse use another default java version than Java 1.5, you can change the configuration in the maven-compiler-plugin.
Go to the folder .m2/repository/org/apache/maven/plugins/maven-compiler-plugin/3.1
Open maven-compiler-plugin-3.1.jar with a zip program.
Go to META-INF/maven and open the plugin.xml
In the following lines:
<source implementation="java.lang.String" default-value="1.5">${maven.compiler.source}</source>
<target implementation="java.lang.String" default-value="1.5">${maven.compiler.target}</target>
change the default-value to 1.6 or 1.8 or whatever you like.
Save the file and make sure it is written back to the zip file.
From now on all new Maven projects use the java version you specified.
Information is from the following blog post: https://sandocean.wordpress.com/2019/03/22/directly-generating-maven-projects-in-eclipse-with-java-version-newer-than-1-5/
To change JDK's version, you can do:
1- Project > Properties
2- Go to Java Build Path
3- In Libraries, select JRE System ... and click on Edit
4- Choose your appropriate version and validate

Looking for a Maven shortcut -- including a jar file in a Maven build

I've inherited a Maven project. I'm just using it as a build tool and I'd like to disturb things as little as possible. I have to make a slight addition to one of the Java files and that addition requires that I include a new jar on the build path. How do I say: here a jar, just use it. It doesn't have to be versioned or depended or downloaded or anything, just use it. Any help would be appreciated.
EDIT: I found this, which actually works (!). If someone who knows about such things could read this answer and if it seems reasonably correct, please close this question as a dup.
EDIT: Nope, I misinterpreted my results. It doesn't seem to work.
By far the best way to manage your dependencies with maven is to get them from a repository, but four total options spring to mind, in order from most desirable to least:
If the jar is a common third-party library, you'll almost certainly find it in some repository somewhere. You just have to add a <dependency> element and possibly a <repository> as well so it knows where to get the dependency from.
A home-grown jar not available in any repo should be deployed to a local repository, like Nexus, which is available to your whole team/company. Then add the dependency to your project just like in option 1. This way it only has to be dealt with once, and everyone else can get the jar via the normal Maven mechanism.
To only deal with the problem locally and not give any reusability of the artifact, you can install it into your local repo (meaning your local cache at ~/.m2/repository) using the install:install-file goal.
Finally, and least desirably, you can use a system-scoped dependency. This means you have the jar file available somewhere in your file system, set the <scope> element of your <dependency> to the value "system", and add a <systemPath> element that contains the full path to the jar in question.
Edit: Since option 4 seems right for you, just put the jar into your project and commit it to your version control. Then, assuming the jar is at lib/foo.jar in your project, add this to your POM's dependencies:
<dependency>
<groupId>some-group</groupId>
<artifactId>some-artifact</artifactId>
<version>1.2.3.4</version>
<scope>system</scope>
<systemPath>${project.basedir}/lib/foo.jar</systemPath>
</dependency>
That's all from memory, but it sounds right.
Here are some related answers:
Maven: keeping dependent jars in project version control
I would not recommend using install:install-file from a POM - if it's a once off requirement you're better using that from the command line and documenting it as a preparation step. However, making the build self-contained or providing a repository with the required artifacts are certainly better options.
Here is how to proceed. Create a separate maven project inspired from the following 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>net.dwst</groupId>
<artifactId>MavenMissingJars</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<name>Maven Missing Jars</name>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-install-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<id>dProguard-4.6</id>
<phase>generate-sources</phase>
<goals>
<goal>install-file</goal>
</goals>
<inherited>false</inherited>
<configuration>
<file>toinstall/4.6/proguard.jar</file>
<groupId>net.sf.proguard</groupId>
<artifactId>proguard</artifactId>
<version>4.6</version>
<packaging>jar</packaging>
<generatePom>true</generatePom>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
Assuming there is a /toinstall/4.6/ directory relative to your pom.xml and that a jar called proguard.jar is in there, calling this plugin will copy the jar from your local directory to your maven local repository.
This has to be executed once, that's why it is preferable to have a separate small maven project for injecting missing jars.
Then, add a dependency in your project using the coordinates (artifactid, version and packaging) you have defined in the above pom.xml.

Categories