Package.getImplementationVersion() returns NULL - java

Thanks in advance for any help.
What I want to achieve is project version (Implementation-Version) is printed in a class when it is initiated so that I can trace the version from log file.
I build a JAR file containing the following classes:
com.company.core.common.ClassA
com.company.core.security.ClassB
com.company.core.sql.ClassC
In constructor of com.company.core.sql.ClassC, I want to call System.out.println() to print out the Implementation-Version stored in META-INF/MANIFEST.MF file by calling this.class.getPackage().getImplementationVersion(), but it is getting null value when the class is initiated via Maven test class.
My MANIFEST.MF file contains the following details:
Manifest-Version: 1.0
Implementation-Title: Company Core Library
Implementation-Version: 1.0
Archiver-Version: Plexus Archiver
Built-By: simon
Implementation-Vendor-Id: com.company.core
Build-Time: 2017-02-18T15:07:33Z
Class-Path: lib/sqljdbc42-4.2.jar lib/log4j-api-2.7.jar lib/log4j-core
-2.7.jar lib/json-20160810.jar lib/junit-4.12.jar lib/hamcrest-core-1
.3.jar
Created-By: Apache Maven 3.3.9
Build-Jdk: 1.8.0_102
Implementation-Vendor: Company
Name: com/company/core/
Implementation-Vendor-Id: com.company.core
Implementation-Title: Company Core Library
Implementation-Version: 1.0
Implementation-Vendor: Company
Would I be able to get the Implementation-Version in Maven test class?
If yes, what have I missed out here?
Thanks.
Regards,
Simon.

Within the development environment all class files are found in a named folder target (e.g. within Eclipse). The package path is represented as a directory structure. For a directory structure the existance of a Manifest is not defined. Therefore the dedicated class loader will ignore all requests for a Manifest. This is the reason the call returns null.
Running in the productive environment your product is packed within a jar-file. In this case it is defined, that there is a Manifest-file. The jar file class loader knows about the manifest file and will display version information correctly.
We helped us, by providing a default of "Implementation Version" if the version is retrieved within the development environment.

Related

ClassNotFoundException for main-class running an executable jar with dependencies

I cannot find the issue here:
I created a jar using a maven plugin, but the dog won't hunt.
The class:
package com.foo.baitshop;
public class Design {
public static void main(String args[]) throws IOException {
int argLength = args.length;
}
}
I unzipped the jar to peek inside and the META-INF folder is in the root and contains the manifest (MANIFEST.MF).
It looks like this:
Manifest-Version: 1.0
Archiver-Version: Plexus Archiver
Created-By: Apache Maven
Built-By: lwhite
Build-Jdk: 9.0.4
Main-Class: com.foo.baitshop.Design;
To Run, i execute the following in the directory holding the jar:
java -jar baitshop2-1.0-SNAPSHOT-jar-with-dependencies.jar
There is no classpath set externally in this environment.
The error message is:
fm-mltp140:target lwhite$ java -jar baitshop2-1.0-SNAPSHOT-jar-with-dependencies.jar
Error: Could not find or load main class com.foo.baitshop.Design;
Caused by: java.lang.ClassNotFoundException: com/foo/baitshop/Design;
Any help would be greatly appreciated.
I think it's the semi-colon:
Main-Class: com.foo.baitshop.Design;
It needs to be removed to be:
Main-Class: com.foo.baitshop.Design
If Maven is generating this, the Maven configuration needs to be debugged to prevent adding the semi-colon. Likely there is a semi-colon in the configuration somewhere.
The associated doc from Oracle.

What causes FileNotFoundException: ...pdq.jar with db2jcc4?

When adding db2jcc4.jar to the system class path, Tomcat 8.0 raises a FileNotFoundException on a jar file that has no apparent reference to my project, pdq.jar.
I couldn't find it anywhere on my system or where it might come from, except through a search which turned up the answer below.
In this case, I have my CATALINA_HOME pointed to C:\tomcat8.0\apache-tomcat-8.0.41 and my project has the following maven dependency defined:
<dependency>
<groupId>com.ibm.db2.jcc</groupId>
<artifactId>db2jcc4</artifactId>
<version>10.1</version>
<scope>system</scope>
<systemPath>${env.CATALINA_HOME}/lib/db2jcc4-10.1.jar</systemPath>
</dependency>
This might happen in the newer versions of Db2 jcc driver:
Beginning with version 4.16 of the IBM Data Server Driver for JDBC and SQLJ, which is shipped with Db2 10.5 on Linux, UNIX, or Windows operating systems, the MANIFEST.MF file for db2jcc4.jar contains a reference to pdq.jar.
IBM Support offers 2 options:
Resolving the problem
To prevent the java.io.FileNotFoundException, you can take one of the following actions:
Edit the MANIFEST.MF file, and remove this line: Class-Path: pdq.jar
Edit the context.xml file for Apache Tomcat, and add an entry like the following one to set the value of scanClassPath to false.
Personally, I prefer the second approach, which can be done as following:
<Context>
...
<JarScanner scanClassPath="false" />
...
</Context>
According to this KB article on IBM, the problem comes from the MANIFEST, which lists pdq.jar, a third party optimization tool.
I had both db2jcc4.jar and db2jcc4.10.1.jar in my lib folder.
While the article suggests editing the MANIFEST file in db2jcc4.jar, version 10.1 does not include this entry at all.
Removing db2jcc4.jar solved my problem, so a solution in this case could also be to upgrade db2jcc4 from an older version to version 10.1, or if that is not possible, edit the manifest file as instructed.
You Just need to update jar db2jcc4.jar to be db2jcc4-10.1.jar
You can find maven dependency / Jar on that link
Kayvan Tehrani's answer explains what's going on here and that this error can be ignored.
Another alternative to clean up the logs is to create a dummy pdq.jar and place it into tomcat's lib folder.
jar -cf pdq.jar ""
(The ": no such file or directory" message from this command is expected.)

NoClassDefFoundError in jackcess

I am working on an RCP application which is based on eclipse plugins. In one of my plugin project I add another plugin project as dependency. Let say Project A has Project B as a dependency defined under its manifest. Project B contains jackcess.jar file as referenced library.
In Project B I have a class called Mirror.java
public Mirror(String source, String template, String target) throws SQLException, IOException {
this.sourceString=source;
this.templateFileString=template;
this.targetFileString=target;
}
inside from project A when I try to create an object of class Mirror
Mirror m = new Mirror(connectionString, "EABase_JET4_empty.eap",platformDB.getAbsolutePath());
I get the following error
java.lang.NoClassDefFoundError:
com/healthmarketscience/jackcess/ImportFilter
build.properties of Project B (containing jackcess.jar)
bin.includes = META-INF/,\
src/main/resources/lib/jackcess-1.2.6.af3.jar
The MANIFEST.MF
Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: MirrorDbToEap
Bundle-SymbolicName: MirrorDbToEap
Bundle-Version: 1.0.0
Export-Package: .,
com.example.jetdb.mirror
Require-Bundle: CommonsIo;bundle-version="2.0.0",
org.apache.commons.lang;bundle-version="2.6.0",
org.apache.commons.logging;bundle-version="1.0.4"
Anyone having any idea what's going wrong here?
Thanks
You are not including the jackcess.jar in the bin.includes in the build.properties file so it is not being included in the RCP build.
Open the build.properties editor and select the jar in the 'Binary Build' selection.
The jar must also appear in the Bundle-ClassPath in the MANIFEST.MF. In the manifest editor in the Runtime tab add the jar to the 'Classpath' section (you should also have '.' for normal plugin code).
It seems the class which is available in compile time, is not available in run time.

How to get jar library name and version from String library name?

I have many jar files in my directory:
some-lib-2.0.jar
some-lib-2.1-SNAPSHOT.jar
some-lib-3.RELEASE.jar
some-lib-R8.jar
some-lib-core-1.jar
some-lib-2.patch2.jar
some-lib-2-alpha-4.jar
some-lib.jar
some-lib2-4.0.jar
How can I get library name and version from file name?
Is regex ((?:(?!-\d)\S)+)-(\S*\d\S*(?:-SNAPSHOT)?).jar$ valid for extract name and version?
The version number in the JAR file name is merely a convention and a default for Maven-built JARs. It may have been overridden, and it is not always reliable reading the version number from just the file name.
A more reliable way for reading version number from JAR is to look inside the JAR file. Here you have a couple of options depending on how the JAR was built:
look at META-INF/maven/.../pom.properies and pom.xml and read the version from that - this should be present for Maven-built binaries
sometimes version number if present in META-INF/MANIFEST.MF under Specification-Version or Implementation-Version properties
If this fails, then fall back to reading version number from the JAR name since there is no other information available.
Naming policy could differ across different libraries, so you aren't able to extract name/version from package name using one rule, for details you should check project docs.
In case of Maven you are able to configure the final name of built artifact with finalName pom.xml configuration option. Maven docs provide nice introduction into pom structure. Below is the example from docs:
<build>
...
<finalName>${artifactId}-${version}</finalName>
...
</build>

Jetty with a custom JUL logger

I feel this should be easier, or I am missing something obvious.
I am trying to use our custom JUL logging library with Jetty. No matter where I put the JAR file for the custom logger, it is not found. I have tried the usual suspects; /lib/, /lib/ext/, /WEB-INF/lib/ and even manually added it to the classpath.
2011-06-29 15:27:34.518::INFO: Started SelectChannelConnector#0.0.0.0:8080
Can't load log handler "net.aw20.logshot.client.LogShotHandler"
java.lang.ClassNotFoundException: net.aw20.logshot.client.LogShotHandler
java.lang.ClassNotFoundException: net.aw20.logshot.client.LogShotHandler
at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
I am starting up Jetty using "-jar start.jar" technique. Searching around, I have spotted a couple of threads that talk about this problem, but with no resolution. Or if there was, they didn't answer with their solution.
Can anyone help on this front?
Thanks
If you start a Java application with "-jar", the normal classpath-arguments are not used any more. What you can do instead is to list the .jar file in a META-INF/MANIFEST.MF file. I.e. I have the following in one of my jar-files:
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.1
Created-By: 20.6-b01 (Sun Microsystems Inc.)
Built-By: user1
Bundle-Vendor: myCompany
Bundle-Version: 1.0.0.1
Implementation-Version: 1.0.0.1
Class-Path: commons.jar lib/hibernate3.jar
and this way the jars are available as part of the Classpath.

Categories