Can't find bootclasspath on jdk9+ - java

The openjdk document "JEP 261: Module System" states that:
"A related option, -Xbootclasspath/a, allows files and directories to be appended to the default bootstrap class path. This option, and the related API in the java.lang.instrument package, is sometimes used by instrumentation agents, so for compatibility it is still supported at run time.
Its value, if specified, is reported via the JDK-specific system property jdk.boot.class.path.append."
However, when I try to use this feature, it does not work. Specifically, I am using Java Agents to do instrumentation.
All works fine on JDK7 & JDK8. On JDK9+ the -Xbootclasspath/a seems to work ok, but the system property jdk.boot.class.path.append is always null.
On java 7/8:
String bootclasspath = System.getProperty(`sun.boot.class.path`);
works as expected.
On java 9:
String bootclasspath = System.getProperty("jdk.boot.class.path.append");
always return null string.
I added some debug code to dump all the system properties, and there appears to be no such property.
I have tried jdk-9.0.4 and jdk-11.0.3 with similar results.
Any ideas on how to get the bootclasspath on JDK9+?

Related

Unable to use AbstractProcessor in IDEs

Motivation:
In our code we have a few places where some methods are run by their name. There are some big if-else-if blocks with each function name and call of the corresponding method (I use the term function to describe just names, for example function X01 might correspond to method SomeClass.functionX01). I've been looking into ways to improve that
Goal:
Write just methods that are annotated with some custom annotation, removing the need to update or even include if-else-if blocks in order to run specific function. Have access to any generated code if any code is generated.
What I did:
I've created first prove of concept using runtime annotations and it proved successful, but slower then if-else-if. Next attempt was with source annotation
I've followed this link for an example, however it did not seam to run in IntelliJ. What I wanted is to have - in this case PersonBuilder class generated, instead there was none. In some cases an error was raised Error:java: Bad service configuration file, or exception thrown while constructing Processor object: javax.annotation.processing.Processor: Provider BuilderProcessor not found
After some Googling and failing to find anything I've turned to book (Core Java, Volume II - Advanced Features - 9th Edition, Polish translation) and there was reccomended to run the following commands:
javac [AbstractProcessor implementation]
javac -processor [Compiled Processor] [other source files to compile]
This worked, however is unsatisfactory as it needs to happen inside IDE (NetBeans and IntelliJ to be specific) automatically during build. Code does not need to be generated on the fly, but programmer must have access to it after build (as in - be able to call methods of generated classes)
Question:
How to have and use generated code used in NetBeans and IntelliJ without the need of using external tools? Is it possible, or using reflection, runtime annotations or external tools is the only way?
Additional info (just in case):
Language level: Java 1.8
JVM versions: 12 and 13
IDEs: NetBeans and IntelliJ

When specifying -javaagent, is it possible to have a jarpath containing = (equal) in it?

Question
Is it possible to use a jarpath containing an equal sign when specifying an agentlib ? For example, using some kind of escaping ?
Note: the syntax to specify the java agent is -javaagent:jarpath[=options] (see the official documentation).
Context
I have a Continuous Integration setup where paths contains an = (equal) sign.
And I have problems running the maven surefire plugin which fails at startup because the agent jar is not found.
I dig a bit and found that
And our command line looks like /<path-to-jre>/bin/java -javaagent:/<path-to-jenkins-workspace>/myProject=myJobName/.repository/org/jacoco/org.jacoco.agent/0.7.9/org.jacoco.agent-0.7.9-runtime.jar=destfile=/<path-to-jenkins-workspace>/myProject=myJobName/target/jacoco.exec,append=true <other arguments to java dropped>.
I made this command work by renaming the project to myProject+myJobName, thus I'm sure that the problem lies with the use of equal.
Note that the above command line is directly generated by maven-surefire-plugin, thus I don't have many options to alter it.
According to Sylvain's comment, this is not possible with OpenJDK 9.
This is probably the same with earlier JDK and the one from Oracle

How can I specify entry-point class and jar archive for JBCO (Java ByteCode Obfuscator)?

I can't guess how can I specify class, which is entry-point of my program (therefore shouldn't be obfuscated), and my jar archive. Please show me an command-line example, how to use JBCO when I have /home/example/myJar.jar and within it com.example.EntryPoint class and my external dependency /home/example/dependencies/dependencyJar.jar.
Also, please, does anybody know if this project is still alive and what jdk it supports?
A lot of time have passed, but recently I have passed across the java transformation frameworks and find out that JBCO now is a part of soot framework, hosted on GitHub, but it is #deprecated as for now. There is a wiki where you can get more info about how to use soot/jbco (if you still want to, on your own risk, even though JBCO is deprecated and not under active development it still from time to time accepts PRs from contributors).
As for the command line options it might be:
java -cp .:/home/example/sootclasses-trunk-jar-with-dependencies.jar soot.jbco.Main -process-dir /home/example/compiled -output-dir /home/example/obfuscated -soot-class-path .:/home/example/myJar.jar -output-format class -app -main-class com.example.EntryPoint -t:9:wjtp.jbco_cr
Soot can process your compiled code as class files (then pass it to -process-dir option) or as jar (then pass it as part of soot-class-path) - soot can process many forms of bytecode (java/scala/.. bytecode, android bytecode, jasmin, jimple). There are also options to specify what is library classes and application or argument classes more precisely, for more info please refer to soot's wiki page.

Java backward compatibility doesn't work

I've created library for encoding/decoding property files. Library has two main purposes:
Encode property file and save it to another file.
Return key value from encoded file (decode file, store result as string in memory, load string to Properties object and return result from properties object).
Everything seems to work fine but today I've noticed that library doesn't work on java 1.5. I've noticed that problem occurs on decoding side so let's focus on this code. Assume that code responsible for decoding looks like that:
String props = "key1=val1\nkey2=val2";
Properties p = new Properties();
p.load(new StringReader(props));
p.list(System.out);
After few tests I saw that the problem is with this line:
p.load(new StringReader(props));
I found that Properties class in java 1.5 doesn't have load(Reader) declaration. To meet java 1.5 API requirements I changed this line to load(InputStream). Everyting works fine now but here is the question.
I use gradle to compile project and I knew that this library should work on java 1.5+ ( I've java 1.7 installed on my computer) so I added to build.gradle those two lines
sourceCompatibility = '1.5'
targetCompatibility = '1.5'
I thought that java compiler will know that I want to compile code with compatibility to java 1.5 and will show appropriate errors. To be sure that it isn't gradle problem I compiled java code from command line but with the same result (compiler doesn't show any errors). So why compiler doesn't show any errors while compiling?
Java 1.5 Properties class API: http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Properties.html
Java 1.6 Properties class API: http://docs.oracle.com/javase/6/docs/api/java/util/Properties.html
[UPDATE]
Neither -source or -target will check API compatibility. If so how can I check it in gradle? As millimoose wrote maven has this plugin (http://mojo.codehaus.org/animal-sniffer-maven-plugin/index.html) but what with gradle?
See the sections of the javac documents named "cross-compiling" and "Cross-Compilation Example".
http://docs.oracle.com/javase/7/docs/technotes/tools/solaris/javac.html#crosscomp-options
Specifically this part:
It is important to use -bootclasspath and -extdirs when
cross-compiling; see Cross-Compilation Example below ....... If you do not
specify the correct version of bootstrap classes, the compiler will
use the old language rules (in this example, it will use version 1.6
of the Java programming language) combined with the new bootstrap
classes, which can result in class files that do not work on the older
platform (in this case, Java SE 6) because reference to non-existent
methods can get included.
The -source switch only instructs the compiler to give a compilation error if you use a language construct not supported in the specified version. For example using try-with-resources with -source 1.6 will result in a compilation error, as it is only supported in Java 7 and higher. Its use is more a sanity check (ie: is my code still compatible with Java version 1.x)
The -target switch instructs the compiler to emit byte code compatible with the specified version. That is: the compiled code can run on the virtual machines of the specified version.
However neither of these switches make the compiler check for compatibility with Java libraries of an earlier Java version. That is why since Java 7, the compiler gives a warning if you use -target 1.6 (or earlier), that you should also specify the -bootclasspath to point to a Java runtime library set of that java version so that it can check if your code is only using classes and methods of that Java version.

How can I specify the LIBPATH on a UniObjects for Java subroutine call?

I am having xml errors due to a LIBPATH setting when calling a UniSubroutine through UOJ.
Referencing the U2 Knowledgebase article SFMA-17048, I tried using the SETENV Unibasic function, but this was not effective.
I am using Unidata 7.2.5 on aix 5.3.
In USER-FORMS/_PACK.LIST.DOC2XML at line 1741 Can't load "/usr/udthome/bin/libxml.so": could not load module /usr/udthome/bin/libxml.so.
Dependent module /usr/optio/eci77/bin/libxerces-c.a could not be loaded.
The module has an invalid magic number.
Could not load module /usr/udthome/bin/libxml.so.
Dependent module /usr/udthome/bin/libxml.so could not be loaded.
More info.
bash-4.2$ ldd libxml.so
libxml.so needs:
Cannot find libxslt4c.a
/usr/lib/libC.a(shr_64.o)
/usr/lib/libC.a(ansi_64.o)
Cannot find libxerces-c.a
/usr/lib/libc_r.a(shr_64.o)
/usr/lib/libC.a(ansicore_64.o)
/usr/lib/threads/libc.a(shr_64.o)
/usr/lib/libC.a(shrcore_64.o)
/usr/lib/libC.a(shr3_64.o)
/usr/lib/libC.a(shr2_64.o)
/unix
/usr/lib/libcrypt.a(shr_64.o)
This sounds like libxerces-c.a is not the version that libxml.so is expecting.
If this is the case, I think you might have 2 options.
Update libxerces to the expected version.
Install the correct version of the libxerces in another location. When setting the LIBPATH environment variable, ensure the path to the expected version is first so it will load that instead of the older version.

Categories

Resources