How to programmatically start OSGi - java

I'm trying to start OSGi in Java as follows:
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleException;
import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.launch.Framework;
import org.osgi.framework.launch.FrameworkFactory;
import java.io.File;
import java.util.*;
public class Launcher {
private static String[] libs = null;
private BundleContext context;
private Launcher() {
FrameworkFactory frameworkFactory = ServiceLoader.load(FrameworkFactory.class).iterator().next();
Map<String, String> config = new HashMap<String, String>();
config.put("osgi.console", "");
config.put("osgi.clean", "true");
config.put("osgi.noShutdown", "true");
config.put("eclipse.ignoreApp", "true");
config.put("osgi.bundles.defaultStartLevel", "4");
config.put("osgi.configuration.area", "./configuration");
// automated bundles deployment
config.put("felix.fileinstall.dir", "./dropins");
config.put("felix.fileinstall.noInitialDelay", "true");
config.put("felix.fileinstall.start.level", "4");
Framework framework = frameworkFactory.newFramework(config);
try {
framework.start();
} catch (BundleException e) {
e.printStackTrace();
}
context = FrameworkUtil.getBundle(this.getClass()).getBundleContext();
Bundle OSGiDmHelloWorldProvider = install("OSGiDmHelloWorldProvider");
Bundle OSGiDmHelloWorldConsumer = install("OSGiDmHelloWorldConsumer");
try {
OSGiDmHelloWorldProvider.start();
OSGiDmHelloWorldConsumer.start();
} catch (BundleException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new Launcher();
}
private String[] getLibs() {
if (libs == null) {
List<String> jarsList = new ArrayList<String>();
File pluginsDir = new File("libs");
for (String jar : pluginsDir.list()) {
jarsList.add(jar);
}
libs = jarsList.toArray(new String[jarsList.size()]);
}
return libs;
}
protected Bundle install(String name) {
String found = null;
for (String jar : getLibs()) {
if (jar.startsWith(name + "_") || jar.startsWith(name + "-")) {
found = String.format("file:libs/%s", jar);
break;
}
}
if (found == null) {
throw new RuntimeException(String.format("JAR for %s not found", name));
}
try {
return context.installBundle(found);
} catch (BundleException e) {
e.printStackTrace();
}
return null;
}
}
Here is the POM:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.github.sarxos</groupId>
<artifactId>equinox-launcher</artifactId>
<version>0.1-SNAPSHOT</version>
<name>equinox-launcher</name>
<description>Launcher for Equinox OSGi runtime</description>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.6.0</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>copy-libs</id>
<phase>compile</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>libs</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.osgi</groupId>
<artifactId>org.osgi.core</artifactId>
<version>6.0.0</version>
</dependency>
</dependencies>
</project>
I get this error:
Exception in thread "main" java.util.NoSuchElementException
at java.util.ServiceLoader$LazyIterator.nextService(ServiceLoader.java:365)
at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:404)
at java.util.ServiceLoader$1.next(ServiceLoader.java:480)
at com.github.sarxos.equinox.Launcher.<init>(Launcher.java:21)
at com.github.sarxos.equinox.Launcher.main(Launcher.java:58)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
What am I getting wron? What do I need to adjust to get it to work?

The error tells you that no FrameworkFactory could be found as you do not have a dependency to any OSGi framework. Add a dependency to equinox or felix in your pom and it should work.

Related

What are new API for old thing HazelcastInstance hzClient = HazelcastClient.newHazelcastClient();?

I follow tutorial at https://www.youtube.com/watch?v=AjpSdbdvIHw
My code
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.anil.hz</groupId>
<artifactId>H</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<version>3.11</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
File Server.java
package com.anil.server;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;
public class Server {
public static void main(String[] args) {
HazelcastInstance hzInstance = Hazelcast.newHazelcastInstance();
IMap<Long, String> map = hzInstance.getMap("testMap");
map.put(1L, "one");
map.put(2L, "two");
}
}
File Student.java
package com.anil.server;
public class Student {
private Long id;
private String sName;
private String city;
public Student(Long id, String sName, String city) {
this.id = id;
this.sName = sName;
this.city = city;
}
}
File Server.java
package com.anil.server;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;
public class Server {
public static void main(String[] args) {
HazelcastInstance hzInstance = Hazelcast.newHazelcastInstance();
IMap<Long, String> map = hzInstance.getMap("testMap");
map.put(1L, "one");
map.put(2L, "two");
}
}
File HZConfig.java
package com.anil.server;
import com.hazelcast.config.Config;
import com.hazelcast.config.JoinConfig;
import com.hazelcast.config.NetworkConfig;
public class HZConfig {
public static Config getConfig(){
Config config = new Config();
NetworkConfig network = config.getNetworkConfig();
network.setPort(5710).setPortCount(20);
network.setPortAutoIncrement(true);
JoinConfig join = network.getJoin();
join.getMulticastConfig().setEnabled(false);
join.getTcpIpConfig().addMember("localhost").setEnabled(true);
config.getManagementCenterConfig().setEnabled(true);
config.getManagementCenterConfig().setUrl("http://localhost:8081/mancenter");
return config;
}
}
File Client.java
package com.anil.server;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.IMap;
public class Client {
public static void main(String[] args) {
HazelcastInstance hzClient = null;
try {
hzClient = HazelcastClient.newHazelcastClient();
IMap<Long, String> testMap = hzClient.getMap("testMap");
System.out.println(testMap.get(1L));
} finally {
hzClient.shutdown();
}
}
}
I catch error at
What are new API for old thing HazelcastInstance hzClient = HazelcastClient.newHazelcastClient(); ?
You are using the following dependency
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<version>3.11</version>
</dependency>
This does not contain the client. The tutorial changes that dependency to hazelcast-all at 3:45, which has the client included. You can also include the client separately using hazelcast-client artifactId.
However 3.11 is a really old version, not supported anymore, you should use the latest release - 5.1 currently. In this release, there is no hazelcast-all jar anymore and the client is included in the main jar. Note that there are some breaking changes between 3.x and 4.x/5.x, but it's mostly just package names.
Base on answer from František Hartman, I add more detail
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.anil.hz</groupId>
<artifactId>H</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<version>5.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.10.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
File Client.java
package com.anil.server;
import com.hazelcast.client.HazelcastClient;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
public class Client {
public static void main(String[] args) {
HazelcastInstance hzClient = null;
try {
hzClient = HazelcastClient.newHazelcastClient();
IMap<Long, String> testMap = hzClient.getMap("testMap");
System.out.println(testMap.get(1L));
} finally {
hzClient.shutdown();
}
}
}
File Server.java
package com.anil.server;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
public class Server {
public static void main(String[] args) {
HazelcastInstance hzInstance = Hazelcast.newHazelcastInstance();
IMap<Long, String> map = hzInstance.getMap("testMap");
map.put(1L, "one");
map.put(2L, "two");
}
}
File HZConfig.java
package com.anil.server;
import com.hazelcast.config.Config;
import com.hazelcast.config.JoinConfig;
import com.hazelcast.config.NetworkConfig;
public class HZConfig {
public static Config getConfig(){
Config config = new Config();
NetworkConfig network = config.getNetworkConfig();
network.setPort(5710).setPortCount(20);
network.setPortAutoIncrement(true);
JoinConfig join = network.getJoin();
join.getMulticastConfig().setEnabled(false);
join.getTcpIpConfig().addMember("localhost").setEnabled(true);
config.getManagementCenterConfig().setConsoleEnabled(true);
config.getManagementCenterConfig().setDataAccessEnabled(true);
config.getManagementCenterConfig().setScriptingEnabled(true);
// config.getManagementCenterConfig().setUrl("http://localhost:8081/mancenter"); // ?
return config;
}
}

picocli does not work with jline3 in cmd.exe

I want to use picocli with jline3. So I create a project with 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>com.flaxel</groupId>
<artifactId>picocli_test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>picocli</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<picocli.version>3.9.3</picocli.version>
<jline.version>3.9.0</jline.version>
</properties>
<dependencies>
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli</artifactId>
<version>${picocli.version}</version>
</dependency>
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli-shell-jline3</artifactId>
<version>${picocli.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.0.2</version>
<configuration>
<archive>
<manifest>
<mainClass>com.flaxel.picocli.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compile-plugin</artifactId>
<version>3.7.0</version>
</plugin>
</plugins>
</build>
Now I have copied a class from the picocli github page:
package com.flaxel.picocli;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
import org.jline.reader.EndOfFileException;
import org.jline.reader.LineReader;
import org.jline.reader.LineReaderBuilder;
import org.jline.reader.MaskingCallback;
import org.jline.reader.ParsedLine;
import org.jline.reader.UserInterruptException;
import org.jline.reader.impl.DefaultParser;
import org.jline.reader.impl.LineReaderImpl;
import org.jline.terminal.Terminal;
import org.jline.terminal.TerminalBuilder;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.ParentCommand;
import picocli.shell.jline3.PicocliJLineCompleter;
/**
* Example that demonstrates how to build an interactive shell with JLine3 and
* picocli.
*
* #since 3.9
*/
public class App {
/**
* Top-level command that just prints help.
*/
#Command(name = "", description = "Example interactive shell with completion", footer = { "",
"Press Ctl-D to exit." }, subcommands = { MyCommand.class, ClearScreen.class })
static class CliCommands implements Runnable {
LineReaderImpl reader;
PrintWriter out;
CliCommands() {
}
public void setReader(LineReader reader) {
this.reader = (LineReaderImpl) reader;
out = reader.getTerminal().writer();
}
#Override
public void run() {
out.println(new CommandLine(this).getUsageMessage());
}
}
/**
* A command with some options to demonstrate completion.
*/
#Command(name = "cmd", mixinStandardHelpOptions = true, version = "1.0", description = "Command with some options to demonstrate TAB-completion"
+ " (note that enum values also get completed)")
static class MyCommand implements Runnable {
#Option(names = { "-v", "--verbose" })
private boolean[] verbosity = {};
#Option(names = { "-d", "--duration" })
private int amount;
#Option(names = { "-u", "--timeUnit" })
private TimeUnit unit;
#ParentCommand
CliCommands parent;
#Override
public void run() {
if (verbosity.length > 0) {
parent.out.printf("Hi there. You asked for %d %s.%n", amount, unit);
} else {
parent.out.println("hi!");
}
}
}
/**
* Command that clears the screen.
*/
#Command(name = "cls", aliases = "clear", mixinStandardHelpOptions = true, description = "Clears the screen", version = "1.0")
static class ClearScreen implements Callable<Void> {
#ParentCommand
CliCommands parent;
#Override
public Void call() throws IOException {
parent.reader.clearScreen();
return null;
}
}
public static void main(String[] args) {
try {
// set up the completion
CliCommands commands = new CliCommands();
CommandLine cmd = new CommandLine(commands);
Terminal terminal = TerminalBuilder.builder().build();
LineReader reader = LineReaderBuilder.builder()
.terminal(terminal)
.completer(new PicocliJLineCompleter(cmd.getCommandSpec()))
.parser(new DefaultParser())
.build();
commands.setReader(reader);
String prompt = "prompt> ";
String rightPrompt = null;
// start the shell and process input until the user quits with Ctrl-D
String line;
while (true) {
try {
line = reader.readLine(prompt, rightPrompt, (MaskingCallback) null, null);
ParsedLine pl = reader.getParser().parse(line, 0);
String[] arguments = pl.words().toArray(new String[0]);
CommandLine.run(commands, arguments);
} catch (UserInterruptException e) {
// Ignore
} catch (EndOfFileException e) {
return;
}
}
} catch (Throwable t) {
t.printStackTrace();
}
}
}
If I run the code in the Eclipse IDE, I can write a command in the console and I get an answer. But if I create a jar file with maven, it does not work. I get the following error:
Error: Unable to initialize main class com.flaxel.picocli.App
Caused by: java.lang.NoClassDefFoundError: org/jline/reader/UserInterruptException
I work with Eclipse 2018-09 and Java 11.
The NoClassDefFoundError occurs because you are missing the JLine classes when running your jar. Try using the shade Maven plugin to create an Uber-jar that contains all the dependencies.
With JLine 3 on Windows, you probably want to add the org.jline:jline-terminal-jansi:3.9.0 dependency in addition to info.picoli:picocli-shell-jline3:3.9.3. Without this (or the jline-terminal-jna dependency) you will get a “dumb” terminal without ANSI colors or autocompletion.
(info.picoli:picocli-shell-jline3:3.9.3 will bring in info.picocli:picocli and org.jline:jline as transitive dependencies, so there is no need to include these explicitly.)
Perfect that works for me. I use the maven shade plugin and add some properties, so I get 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>com.flaxel</groupId>
<artifactId>picocli_test</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>picocli</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<picocli.version>3.9.3</picocli.version>
<jline.version>3.9.0</jline.version>
</properties>
<dependencies>
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli</artifactId>
<version>${picocli.version}</version>
</dependency>
<dependency>
<groupId>info.picocli</groupId>
<artifactId>picocli-shell-jline3</artifactId>
<version>${picocli.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<mainClass>com.flaxel.picocli.App</mainClass>
<addDefaultImplementationEntries>true</addDefaultImplementationEntries>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compile-plugin</artifactId>
<version>3.7.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<shadedArtifactAttached>true</shadedArtifactAttached>
<shadedClassifierName>jar-with-dependencies</shadedClassifierName>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
EDIT
I have at least one question. If I start the application and want to use the tab completion, it does not work. So I get no completion, only four spaces are set:
Feb. 07, 2019 6:50:29 NACHM. org.jline.utils.Log logr
WARNING: Unable to create a system terminal, creating a dumb terminal (enable debug logging for more information)
prompt> cmd
Or did I something wrong?

Bind maven plugin execution to only listed submodules and not all child modules

Hi i have created a maven plugin
package com.common.gflogging.gen.parser;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.slf4j.Logger;
import com.thoughtworks.qdox.JavaDocBuilder;
import com.thoughtworks.qdox.model.JavaClass;
import com.thoughtworks.qdox.model.JavaField;
/**
* This is where we take in java classes and check if they have loggers
*
*/
#Mojo( name = "codeloggersparser" )
public class CodeLoggersParser extends AbstractMojo {
#Parameter( defaultValue = "${project}", required = true, readonly = true )
private MavenProject project;
private String tier;
#Override
public void execute() throws MojoExecutionException, MojoFailureException {
File f = new File( "/home/xxx/Desktop/list" + "." + tier );
if ( !f.exists() ) {
try {
f.createNewFile();
} catch ( IOException e ) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
String currentSrcFolder = project.getCompileSourceRoots().iterator().next();
JavaDocBuilder builder = new JavaDocBuilder();
builder.addSourceTree( new File( currentSrcFolder ) );
JavaClass[] classes = builder.getClasses();
for ( JavaClass jClass : classes ) {
if ( jClass.getName().contains( "AuthenticationConfiguration" ) ) {
System.out.println( jClass.getName() );
}
for ( JavaField jFiled : jClass.getFields() ) {
if ( jFiled.getType().getJavaClass().isA( new JavaClass( Logger.class.getName() ) ) ) {
try {
Files.write( f.toPath(), (jClass.getFullyQualifiedName() + "\n").getBytes(), StandardOpenOption.APPEND );
} catch ( IOException e ) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
And i have 4 big maven projects, every project has this maven plugin inovoked in the parent pom (It's basically a plugin to scan code i don't want to include it in every child pom).
One of the 4 parent pom.
<build>
<plugins>
<plugin>
<groupId>com.common</groupId>
<artifactId>gflogginggen</artifactId>
<version>0.0.1-SNAPSHOT</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>codeloggersparser</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<!-- This is so we avoid M2E maven eclipse plugin not covered lifecycle messages -->
<pluginManagement>
<plugins>
<plugin>
<groupId>org.eclipse.m2e</groupId>
<artifactId>lifecycle-mapping</artifactId>
<version>1.0.0</version>
<configuration>
<lifecycleMappingMetadata>
<pluginExecutions>
<pluginExecution>
<pluginExecutionFilter>
<groupId>com.common</groupId>
<artifactId>gflogginggen</artifactId>
<versionRange>[0.0,)</versionRange>
<goals>
<goal>codeloggersparser</goal>
</goals>
</pluginExecutionFilter>
<action>
<ignore></ignore>
</action>
</pluginExecution>
</pluginExecutions>
</lifecycleMappingMetadata>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
<modules>
<module>1</module>
<module>2</module>
<module>3</module>
<module>gflogginggen</module>
</modules>
Defining the maven execution in the super pom will execute on all child submodules, instead of that i only want list modules to execute it, is that doable ?

My Jar launches using JDK7, but not using JDK1.8.0_101. Why not? Error: Could not find or load main class

So, I'm trying to launch a jar application that I've built, but I'm encountering a very weird issue. When I tried to launch the application on the command line using java -jar MyCookie.jar, I received the following error: Error: Could not find or load main class
Now I know that this is a common error. It is basically telling me that the JVM can't find the main class (or that there is an issue with the main class). Naturally, the first things that I checked were:
A) Did I use the right FQCN, and spell it properly? YES.
B) Did I use MyCookie.jar instead of simply MyCookie in CMD, and main.java.MyCookie.mainClass in the manifest instead of main.java.MyCookie.mainClass.class? YES.
C) Is the desired class actually located in the JAR, or in the Class-Path? YES, The class is located in the main.java.MyCookie package, located within the MyCookie.jar.
After checking these things, I suspected something might be off with Java, especially as I have 4 different java installations on my machine (jre7, jre1.8.0_101, jdk1.7.0_80, jdk1.8.0_101), so I attempted to run the executable jar application on the command line with each different version.
Interestingly enough, I discovered that both the 1.8.0 jre and JDK produced the previously mentioned error, but that the application executed properly using both jre7 and jdk1.7.0_80. Not surprisingly java -jar MyCookie.jar wasn't working because my "java" was set to jdk1.8.0.
It may be a long-shot, but does anyone have any idea why my application may work in JSE7, but trigger a failure to load main class in 1.8.0?
I'm using Maven as a build tool, my main class is mainView, which looks like this:
package main.java.myCookie;
import main.java.gls.entities.Emp;
import main.java.gls.entities.JobStatus;
import main.java.gls.event.StringEventListener;
import main.java.gls.util.JustOneLock;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.EventListener;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.ExecutionException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.PersistenceContext;
import javax.persistence.PersistenceUnit;
import javax.swing.JComponent;
import main.java.myCookie.background.fetchEmpList;
import main.java.myCookie.background.fetchStatusList;
import main.java.myCookie.interfaces.Main;
public class mainView
extends javax.swing.JFrame
implements Main
{
#PersistenceUnit
final private EntityManagerFactory emFactory = javax.persistence.Persistence.createEntityManagerFactory("JobEntitiesPU");
#PersistenceContext
final private EntityManager em = emFactory.createEntityManager();
Properties config = new Properties();
ArrayList<EventListener> listenerList = new ArrayList<EventListener>();
//set from property file in working directory
String defaultPrinter;
ArrayList<Integer> statusExceptionList = new ArrayList<Integer>();
ArrayList<Integer> statusLockedList = new ArrayList<Integer>();
ArrayList<JobStatus> adjustedStatusList = new ArrayList<JobStatus>();
ArrayList<JobStatus> statusList = new ArrayList<JobStatus>();
boolean statusListFetched = false;
int defaultEmpId;
Emp defaultEmp;
Emp noEmp;
ArrayList<Emp> empList = new ArrayList<Emp>();
boolean empListFetched = false;
PanelManager panelManager;
public mainView()
{
lockTest();
init();
}
private void lockTest()
{
JustOneLock jol = new JustOneLock("TimeClock");
if ( jol.isAppActive() )
{
System.out.println("Instance of TimeClock is already Running");
System.exit(1);
}
}
private void init()
{
MainSingleton.getInstance().setMain(this);
this.openPropertiesFromFile();
this.fetchEmpList();
this.fetchStatusList();
initComponents();
panelManager = new PanelManager();
this.setVisible(true);
}
private void openPropertiesFromFile()
{
System.out.println( "Current Working Directory: "+System.getProperty("user.dir"));
//get properties file
try
{
this.config.load(new FileInputStream( System.getProperty("user.dir")+"\\main.java.myCookie.properties"));
} catch (IOException ex)
{
Logger.getLogger(mainView.class.getName()).log(Level.SEVERE, null, ex);
}
//get default user if it exists
if ( config.containsKey("DEFAULT_USER") )
{
System.out.println( "DEFAULT_USER: "+config.getProperty("DEFAULT_USER") );
this.defaultEmpId = Integer.parseInt( config.getProperty("DEFAULT_USER") );
}
else
{
System.out.println( "DEFAULT_USER: NOT FOUND (set to 1000)" );
this.defaultEmpId = 1000;
}
//get default printer if it exists
if ( config.containsKey("DEFAULT_PRINTER") )
{
System.out.println( "DEFAULT_PRINTER: "+config.getProperty("DEFAULT_PRINTER") );
this.defaultPrinter = config.getProperty("DEFAULT_PRINTER");
}
else
{
System.out.println( "DEFAULT_PRINTER: NOT FOUND" );
this.defaultPrinter = "myPrinter";
}
//get status exceptions if it exists ( comma delineated )
if ( config.containsKey("STATUS_EXCEPTIONS") )
{
System.out.println( "STATUS_EXCEPTIONS list found" );
String[] rawSE = config.getProperty("STATUS_EXCEPTIONS").split(",");
for ( String s : rawSE )
{
this.statusExceptionList.add(Integer.parseInt(s));
}
}
else
{
System.out.println( "STATUS_EXCEPTIONS list NOT found" );
}
//get locked status list if it exists ( coma delineated )
if ( config.containsKey("STATUS_LOCKED") )
{
System.out.println( "STATUS_LOCKED list found" );
String[] rawSL = config.getProperty("STATUS_LOCKED").split(",");
for ( String s : rawSL )
{
this.statusLockedList.add(Integer.parseInt(s));
}
}
else
{
System.out.println( "STATUS_LOCKED list NOT found" );
}
}
private void fetchEmpList()
{
final fetchEmpList task = new fetchEmpList();
task.addPropertyChangeListener
(
new PropertyChangeListener()
{
#Override
public void propertyChange( PropertyChangeEvent evt )
{
if ( "DONE".equals( evt.getNewValue().toString() ) )
{
try {
fetchEmpListDone(task.get());
} catch (InterruptedException ex) {
Logger.getLogger(mainView.class.getName()).log(Level.SEVERE, null, ex);
} catch (ExecutionException ex) {
Logger.getLogger(mainView.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
);
task.execute();
}
private void fetchStatusList()
{
final fetchStatusList task = new fetchStatusList();
task.addPropertyChangeListener
(
new PropertyChangeListener()
{
#Override
public void propertyChange( PropertyChangeEvent evt )
{
if ( "DONE".equals( evt.getNewValue().toString() ) )
{
try{
fetchStatusListDone( task.get() );
} catch (InterruptedException ex)
{
Logger.getLogger(mainView.class.getName()).log(Level.SEVERE, null, ex);
} catch (ExecutionException ex)
{
Logger.getLogger(mainView.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
);
task.execute();
}
private void fetchEmpListDone( List<Emp> empList )
{
for( Emp e : empList )
{
//removes non-current employees
if ( e.getEmpQuit() == null )
{
this.empList.add(e);
}
//employee 1000: No Owner
if ( e.getEmpNum() == 1000 )
{
this.noEmp = e;
}
//sets default emp
if ( e.getEmpNum() == this.defaultEmpId )
{
this.defaultEmp = e;
}
}
this.empListFetched = true;
}
private void fetchStatusListDone( List<JobStatus> statusList )
{
//only add status types that are not in the exception list
for( JobStatus js : statusList )
{
this.statusList.add(js);
if ( !this.statusExceptionList.contains(js.getId()) )
{
this.adjustedStatusList.add(js);
}
}
this.statusListFetched = true;
}
#Override
public ArrayList<Integer> getStatusExceptionList()
{
return this.statusExceptionList;
}
#Override
public ArrayList<JobStatus> getAdjustedStatusList()
{
return this.adjustedStatusList;
}
#Override
public ArrayList<Integer> getStatusLockedList()
{
return this.statusLockedList;
}
#Override
public String getDefaultPrinter()
{
return this.defaultPrinter;
}
#Override
public Emp getDefaultEmp()
{
return this.defaultEmp;
}
#Override
public Emp getNoEmp()
{
return this.noEmp;
}
#Override
public ArrayList<Emp> getEmpList()
{
return this.empList;
}
#Override
public boolean empListFetched()
{
return this.empListFetched;
}
#Override
public List<JobStatus> getStatusList()
{
return this.statusList;
}
#Override
public boolean statusListFetched()
{
return this.statusListFetched;
}
#Override
public EntityManager getEM()
{
return this.em;
}
#Override
public JComponent getParentContainer()
{
return this.mainPanel;
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
private void initComponents() {
myCookieLabel = new javax.swing.JLabel();
mainPanel = new javax.swing.JPanel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("myCookie");
setMinimumSize(new java.awt.Dimension(640, 480));
setResizable(false);
getContentPane().setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());
myCookieLabel.setBackground(javax.swing.UIManager.getDefaults().getColor("Button.disabledShadow"));
myCookieLabel.setFont(new java.awt.Font("Tahoma", 0, 24)); // NOI18N
myCookieLabel.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
myCookieLabel.setText("Steve Pro");
getContentPane().add(myCookieLabel, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 0, 640, 40));
mainPanel.setBorder(javax.swing.BorderFactory.createBevelBorder(javax.swing.border.BevelBorder.RAISED));
mainPanel.setLayout(new org.netbeans.lib.awtextra.AbsoluteLayout());
getContentPane().add(mainPanel, new org.netbeans.lib.awtextra.AbsoluteConstraints(0, 40, 640, 440));
pack();
}
/**
* #param args the command line arguments
*/
public static void main(String args[])
{
java.awt.EventQueue.invokeLater(
new Runnable()
{
#Override
public void run()
{
new mainView();
}
}
);
}
// Variables declaration - do not modify
private javax.swing.JPanel mainPanel;
private javax.swing.JLabel myCookieLabel;
// End of variables declaration
#Override
public void addStringEventListener ( StringEventListener stringEventListener )
{
listenerList.add( stringEventListener );
}
#Override
public void removeStringEventListener ( StringEventListener stringEventListener )
{
listenerList.remove( stringEventListener );
}
private void fireStringEvent( String string )
{
for ( EventListener l : listenerList )
{
if ( l instanceof StringEventListener )
{
((StringEventListener) l).stringEventFired(string);
}
}
}
}
My POM:
<?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.glsarchives</groupId>
<artifactId>myCookie</artifactId>
<version>1.0</version>
<packaging>jar</packaging>
<dependencies>
<dependency>
<groupId>org.netbeans.external</groupId>
<artifactId>AbsoluteLayout</artifactId>
<version>0.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.businessobjects.sdk</groupId>
<artifactId>cecore</artifactId>
<version>0.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.businessobjects.sdk</groupId>
<artifactId>celib</artifactId>
<version>0.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.businessobjects.sdk</groupId>
<artifactId>ceplugins</artifactId>
<version>0.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.businessobjects.sdk</groupId>
<artifactId>cereports</artifactId>
<version>0.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.businessobjects.sdk</groupId>
<artifactId>cesession</artifactId>
<version>0.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.businessobjects.sdk</groupId>
<artifactId>ceutils</artifactId>
<version>0.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.lucee</groupId>
<artifactId>commons-logging</artifactId>
<version>1.1.1</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.dspace.xmlui.concurrent</groupId>
<artifactId>Concurrent</artifactId>
<version>0.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.businessobjects.sdk</groupId>
<artifactId>corbaidl</artifactId>
<version>0.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>2.5.2</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>javax.persistence</artifactId>
<version>0.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.33-bin</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.businessobjects.sdk</groupId>
<artifactId>rascore</artifactId>
<version>0.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.9.1</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>org.lucee</groupId>
<artifactId>xml-apis</artifactId>
<version>0.0</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.glsarchives</groupId>
<artifactId>GLSLib</artifactId>
<version>1.1.2-SNAPSHOT</version>
<type>jar</type>
</dependency>
</dependencies>
<!--Build Settings-->
<build>
<sourceDirectory>./src</sourceDirectory>
<finalName>myCookie-${project.version}</finalName>
<plugins>
<!-- Maven Compiler Plugin -->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<!-- Maven-Dependency-Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<!-- Maven-Jar-Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>main.java.myCookie.mainView</mainClass>
</manifest>
<manifestEntries>
<Class-Path>lib/</Class-Path>
<Class-Path>myCookie-1.0</Class-Path>
</manifestEntries>
</archive>
</configuration>
</plugin>
<!-- Maven Resources Plugin -->
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<version>3.0.1</version>
<executions>
<!-- Copies resource files that can be accessed by the user (unpackaged resources), such as configuration and properties files to the installation directory -->
<execution>
<id>copy-internal-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${basedir}/target</outputDirectory>
<resources>
<resource>
<includes>
<include>**/*.properties</include>
</includes>
<directory>${basedir}/src/main/resources/external</directory>
<targetPath>${project.build.directory}/</targetPath>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>${project.basedir}/src/main/java/gls_desktop/resources</directory>
<targetPath>main/java/gls_desktop/resources</targetPath>
</resource>
<resource>
<directory>${project.basedir}/src/main/java/gls_desktop/xml</directory>
<targetPath>main/java/gls_desktop/xml</targetPath>
</resource>
<resource>
<directory>${project.basedir}/src/main/java/gls_desktop/jCalendar</directory>
<targetPath>main/java/gls_desktop/jCalendar</targetPath>
<includes>
<include>Bundle.properties</include>
</includes>
</resource>
<resource>
<directory>${project.basedir}/src/main/java/gls_desktop/jCalendar/images</directory>
<targetPath>main/java/gls_desktop/jCalendar/images</targetPath>
</resource>
</resources>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
</project>
MANIFEST.MF:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: bsnider
Class-Path: myCookie-1.0 lib/AbsoluteLayout-0.0.jar lib/cecore-0.0.jar
lib/celib-0.0.jar lib/ceplugins-0.0.jar lib/cereports-0.0.jar lib/ce
session-0.0.jar lib/ceutils-0.0.jar lib/commons-logging-1.1.1.jar lib
/Concurrent-0.0.jar lib/corbaidl-0.0.jar lib/eclipselink-2.5.2.jar li
b/javax.persistence-0.0.jar lib/log4j-1.2.17.jar lib/mysql-connector-
java-5.1.33-bin.jar lib/rascore-0.0.jar lib/xercesImpl-2.9.1.jar lib/
xml-apis-1.3.04.jar lib/xml-apis-0.0.jar lib/GLSLib-1.1.2-20170210.20
0207-1.jar lib/commons-lang-2.1.jar lib/serialization.jar-0.0.jar lib
/ebus405-0.0.jar lib/MetafileRenderer-0.0.jar lib/rasapp-0.0.jar lib/
javax.mail-1.5.0.jar lib/activation-1.1.jar lib/org.eclipse.persisten
ce.jpa-2.6.4.jar lib/org.eclipse.persistence.asm-2.6.4.jar lib/org.ec
lipse.persistence.antlr-2.6.4.jar lib/javax.json-1.0.4.jar lib/org.ec
lipse.persistence.jpa.jpql-2.6.4.jar lib/org.eclipse.persistence.core
-2.6.4.jar lib/imgscalr-lib-4.2.jar lib/awtextra-0.0.jar lib/ReportPr
inter-0.0.jar
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_101
Main-Class: main.java.myCookie.mainView

Java NoClassDefFoundError using maven [duplicate]

This question already has answers here:
Including all the jars in a directory within the Java classpath
(25 answers)
Closed 6 years ago.
I get a
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/codec/binary/Hex
when i execute my code.
I have looked through a number of examples on this exception on stack overflow but nothing seems to help. My pom.xml looks like this
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.10</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>2.4.3</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.12.4</version>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
Code to reproduce it looks like this
package com.mypackage;
import java.util.*;
import java.io.*;
import java.security.*;
import org.apache.commons.codec.binary.Hex;
public class Test{
private byte[] m_key;
private static String resourceFolder = System.getenv("SEABED_HOME").toString() + "/testing" + "/resources";
public static void main(String[] args)
{
Test t = new Test();
t.readKey();
}
public byte[] generateKey()
{
SecureRandom scr = new SecureRandom();
byte[] key = new byte[32];
scr.nextBytes(key);
return key;
}
private void readKey()
{
BufferedReader br = null;
try{
br = new BufferedReader(new FileReader(resourceFolder + "/.seabedkey"));
m_key = Hex.decodeHex(br.readLine().toCharArray());
}
catch(Exception e)
{
if(e instanceof FileNotFoundException)
{
System.out.println("Key not found, generating now");
writeKey(generateKey());
readKey();
return;
}
e.printStackTrace();
}
finally
{
if(br != null)
{
try
{
br.close();
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
}
private void writeKey(byte[] key)
{
try{
FileOutputStream fos = new FileOutputStream(resourceFolder + "/.seabedkey");
fos.write(key);
fos.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
}
I execute it like this
java -cp target/mypackage-1.0-SNAPSHOT.jar:~/.m2/repository/commons-codec/commons-codec/1.10/commons-codec-1.10.jar com.mypackage.Test
It compiles but then at runtime it looks like the class cannot be found. I tried changing the scope of the dependency to provided but apparently that is not the right way to use it so I switched back to the default which is compile. I can find the jar in my .m2 folder so I am sure it is there.
You're misspelling repository in your manual classpath specification.
Probably the separator, ; for windows : for Unix
if you are running in windows
java -cp "target/mypackage-1.0-SNAPSHOT.jar;~/.m2/repository/commons-codec/commons-codec/1.10/commons-codec-1.10.jar" com.mypackage.Test
Linux
java -cp "target/mypackage-1.0-SNAPSHOT.jar:~/.m2/repository/commons-codec/commons-codec/1.10/commons-codec-1.10.jar" com.mypackage.Test

Categories