Javacpp: problem with linked library - symbol not found in flat namespace - javacpp

I'm trying to use javacpp library. I've prepared c-lib with one function
char * hello(const char * name);
and build it with cmake (on mac, with clang++)
Also I've prepared config file for javacpp
package arrival;
import org.bytedeco.javacpp.annotation.*;
import org.bytedeco.javacpp.tools.*;
#Properties(
value = #Platform(
includepath = {"/Users/valentina.baranova/external/kotlin-cloud/greeter/include/"},
include = {"greeter.h"},
library = "greeter-jni",
link = {"greeter"},
linkpath = {"/Users/valentina.baranova/external/kotlin-cloud/greeter/build/"}
),
target = "arrival.greeter"
)
public class GreeterConfig implements InfoMapper {
public void map(InfoMap infoMap) {
}
}
javacpp prepared library libgreeter-jni.dylib, but when I try to call hello function I got an error
dlopen(/Users/valentina.baranova/external/kotlin-cloud/greeter-javacpp/target/classes/arrival/macosx-x86_64/libgreeter-jni.dylib, 0x0001): symbol not found in flat namespace '__Z5helloPKc'
What I'm doing wrong? In debug I see that Loader.load() loads both libraries.
UPD:
Loader.load() is loaded in autogenerated greeter class.
Function hello there is in both libraries but it has different name
nm libgreeter-jni.dylib | grep hello
0000000000001f70 T _Java_arrival_greeter_hello__Ljava_lang_String_2
0000000000001ce0 T _Java_arrival_greeter_hello__Lorg_bytedeco_javacpp_BytePointer_2
U __Z5helloPKc
nm libgreeter.dylib | grep hello
0000000000003f50 T _hello

Related

Accessing JUnit version during runtime

Is there a way to access the JUnit5 version during runtime?
E.g.
...
System.out.printf( "JUnit: %s\n", junit.runner.Version.id() );
...
worked fine for JUnit4.
I am looking for the "counterpart" for JUnit5
THANKS :-)
There is no single "JUnit 5" version number.
There are three of them. They are listed on junit.org:
All artifacts of these three groups contain version information packaged
a) into their module descriptor and
b) into their manifest files.
For Jupiter for example, you may use
a) org.junit.jupiter.api.Test.class.getModule().getDescriptor().getVersion()
or b) org.junit.jupiter.api.Test.class.getPackage().getImplementationVersion()
to access Jupiter's version information at runtime.
Thanks for your answer, but I am still having problems.
E.g. I can not access ".getVersion()"
Anyway
...
import java.lang.module.ModuleDescriptor;
import java.lang.module.ModuleDescriptor.Version;
import java.util.Optional;
import org.junit.jupiter.api.Test;
import org.junit.platform.runner.JUnitPlatform;
...
String getJupiterVersionFromModuleDescriptor(){
final Class<Test> clazz = org.junit.jupiter.api.Test.class;
final Module module = clazz.getModule();
final ModuleDescriptor moduleDescriptor = module.getDescriptor();
final Optional<Version> optionalVersion = moduleDescriptor.version();
final Version version = optionalVersion.get();
return version.toString();
}
String String getPlatformVersionFromModuleDescriptor(){
final Class<JUnitPlatform> clazz = org.junit.platform.runner.JUnitPlatform.class;
final Module module = clazz.getModule();
final ModuleDescriptor moduleDescriptor = module.getDescriptor();
final Optional<Version> optionalVersion = moduleDescriptor.version();
final Version version = optionalVersion.get();
return version.toString();
}
String getJupiterVersionFromManifest(){
final Class<Test> clazz = org.junit.jupiter.api.Test.class;
final Package pakage = clazz.getPackage();
final String version = pakage.getImplementationVersion();
return version;
}
String getPlatformVersionFromManifest(){
final Class<JUnitPlatform> clazz = org.junit.platform.runner.JUnitPlatform.class;
final Package pakage = clazz.getPackage();
final String version = pakage.getImplementationVersion();
return version;
}// delivers null in my case - getPlatformVersionFromModuleDescriptor() reports 1.5.1 on my machine
works and of course:
org.junit.jupiter.api.Test.class.getModule().getDescriptor().version()
org.junit.platform.runner.JUnitPlatform.class.getModule().getDescriptor().version()
org.junit.jupiter.api.Test.class.getPackage().getImplementationVersion()
org.junit.platform.runner.JUnitPlatform.class.getPackage().getImplementationVersion()
works also.
Currently I am using:
String getJupiterVersion(){
final Class<Test> testClass = org.junit.jupiter.api.Test.class;
final Optional<Version> optionalVersion = testClass.getModule().getDescriptor().version();
return optionalVersion.isPresent() ? optionalVersion.get().toString() : testClass.getPackage().getImplementationVersion();
}
String getPlatformVersion(){
final Class<JUnitPlatform> jUnitPlatformClass = org.junit.platform.runner.JUnitPlatform.class;
final Optional<Version> optionalVersion = jUnitPlatformClass.getModule().getDescriptor().version();
return optionalVersion.isPresent() ? optionalVersion.get().toString() : jUnitPlatformClass.getPackage().getImplementationVersion();
}
Further: Get jar version in runtime might be helpful.
Anyway, I am still having problems to access the vintage version.
E.g. org.junit.vintage.engine.VintageTestEngine is not accessible ???
And just recently on some machine running JUnit 5.4 getDescriptor() resp. e.g. org.junit.jupiter.api.Test.class.getModule().getDescriptor() delivered null.
I like to have a way of identifying the JUnit version that runs on any JUnit 5 installation.

declare ITD static method on multiple types

I would like to declare a static method (like void main(String..args)) on every subtype of my App class.
public aspect Aspects pertypewithin(App+) {
protected Class appClass;
after() : staticinitialization(App+) && !staticinitialization(App) {
StaticPart point = thisJoinPointStaticPart;
Signature signature = point.getSignature();
Class declaringType = signature.getDeclaringType();
this.appClass = declaringType;
}
public static void App.main(String...args) {
// how do i make this appear on every subtype of App, not just App
}
}
Is this possible with AspectJ?
The usual pattern for adding a set of non-static methods to multiple classes is to define an interface + implementing methods within an aspect and use declare parents in order to make the target classes implement the interface.
Unfortunately this does not work for static methods like main because static methods cannot be defined via an interface. On the other hand, if you have a class MyApp extends App you can call java -cp ... MyApp, i.e. its parent main method will automatically be used.
Now let us assume that for some reason you want the contents of the generated main methods to be somehow different. In this case you really need to generate one method per class. For that purpose you can use a new feature introduced in AspectJ 1.8.2 and described in the release notes: annotation processing support. Here is some self-consistent sample code. I compiled it from the command line because from Eclipse I failed to get it running according to AspectJ maintainer Andy Clement's description.
Okay, let's say we have two project directories somewhere in a base directory called java-src. The directory layout be like this:
java-src
SO_AJ_ITD_AddMainMethodToAllSubclasses_AJ
src\de\scrum_master\app\App.java
src\de\scrum_master\app\BarApp.java
src\de\scrum_master\app\FooApp.java
compile_run.bat
SO_AJ_ITD_AddMainMethodToAllSubclasses_APT
src\de\scrum_master\app\EntryPoint.java
src\de\scrum_master\aspect\EntryPointProcessor.java
src\META-INF\services\javax.annotation.processing.Processor
In project SO_AJ_ITD_AddMainMethodToAllSubclasses_AJ we have our Java classes:
package de.scrum_master.app;
#EntryPoint
public class App {
public void doSomething() {
System.out.println("Doing something");
}
}
package de.scrum_master.app;
public class FooApp extends App {
public void doFoo() {
System.out.println("Doing foo");
}
public int add(int a, int b) {
return a + b;
}
}
package de.scrum_master.app;
public class BarApp extends App {
public void doBar() {
System.out.println("Doing bar");
}
public int multiply(int a, int b) {
return a * b;
}
}
In project SO_AJ_ITD_AddMainMethodToAllSubclasses_APT we have our marker annotation, the annotation processor and processor description file for the META-INF directory of our processor.jar:
Please note: The annotation is #Inherited when applied to classes. This is important in order to make the annotation processor find it.
package de.scrum_master.app;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
#Retention(RetentionPolicy.RUNTIME)
#Target(ElementType.TYPE)
#Inherited
public #interface EntryPoint {}
The annotation processor creates one aspect per annotated class. Each aspect does the following:
Add a main method which
instantiates an object of the target class,
always calls the base method doSomething() upon the target instance,
searches the target class for other simple non-static methods without parameters and calls these methods, just so as to show some fancy and dynamic stuff and make the resulting aspects look a bit different.
package de.scrum_master.aspect;
import java.io.*;
import javax.tools.*;
import java.util.*;
import javax.annotation.processing.*;
import javax.lang.model.*;
import javax.lang.model.element.*;
import de.scrum_master.app.EntryPoint;
#SupportedAnnotationTypes(value = { "*" })
#SupportedSourceVersion(SourceVersion.RELEASE_7)
public class EntryPointProcessor extends AbstractProcessor {
private Filer filer;
#Override
public void init(ProcessingEnvironment env) {
filer = env.getFiler();
}
#Override
public boolean process(Set<? extends TypeElement> elements, RoundEnvironment env) {
// Discover elements marked with #EntryPoint
for (Element element : env.getElementsAnnotatedWith(EntryPoint.class)) {
// Skip non-class elements
if (element.getKind() != ElementKind.CLASS)
continue;
String packageName = element.getEnclosingElement().toString().substring(8);
String className = element.getSimpleName().toString();
String aspectName = "MainMethodAspect_" + className;
// For each marked class, create an aspect adding a 'main' method
String aspectSource = createAspectSource(element, packageName, className, aspectName);
writeAspectSourceToDisk(element, packageName, aspectName, aspectSource);
}
return true;
}
private String createAspectSource(Element element, String packageName, String className, String aspectName) {
String variableName = className.substring(0, 1).toLowerCase() + className.substring(1);
StringBuilder aspectSource = new StringBuilder()
.append("package " + packageName + ";\n\n")
.append("public aspect " + aspectName + " {\n")
.append(" public static void " + className + ".main(String[] args) {\n")
.append(" " + className + " " + variableName + " = new " + className + "();\n")
.append(" " + variableName + ".doSomething();\n");
for (Element childElement : element.getEnclosedElements()) {
// Skip everything which is not a non-static method
if (childElement.getKind() != ElementKind.METHOD || childElement.getModifiers().contains(Modifier.STATIC))
continue;
ExecutableElement method = (ExecutableElement) childElement;
// Skip methods with parameters or named 'doSomething'
if (!method.getParameters().isEmpty() || method.getSimpleName().toString().equals("doSomething"))
continue;
// Add call to found method
aspectSource.append(" " + variableName + "." + method.getSimpleName() + "();\n");
}
aspectSource
.append(" }\n")
.append("}\n");
return aspectSource.toString();
}
private void writeAspectSourceToDisk(Element element, String packageName, String aspectName, String aspectSource) {
try {
JavaFileObject file = filer.createSourceFile(packageName + "." + aspectName, element);
file.openWriter().append(aspectSource).close();
System.out.println("Generated aspect " + packageName + "." + aspectName + " to advise " + element);
} catch (IOException ioe) {
// Message "already created" can appear if processor runs more than once
if (!ioe.getMessage().contains("already created"))
ioe.printStackTrace();
}
}
}
The processor description file src\META-INF\services\javax.annotation.processing.Processor for APT looks like this:
de.scrum_master.aspect.EntryPointProcessor
How to compile and run: Last, but not least here is a (Windows) batch file SO_AJ_ITD_AddMainMethodToAllSubclasses_AJ\compile_run.bat which
compiles the APT project and packages it into a JAR,
compiles the other project including APM aspect code generation and finally
runs each of the three Java classes, testing if their main methods actually work as expected:
#echo off
set SRC_PATH=C:\Users\Alexander\Documents\java-src
set ASPECTJ_HOME=C:\Program Files\Java\AspectJ
echo Building annotation processor
cd "%SRC_PATH%\SO_AJ_ITD_AddMainMethodToAllSubclasses_APT"
rmdir /s /q bin
del /q processor.jar
call "%ASPECTJ_HOME%\bin\ajc.bat" -8 -sourceroots src -d bin -cp "c:\Program Files\Java\AspectJ\lib\aspectjrt.jar"
jar -cvf processor.jar -C src META-INF -C bin .
echo.
echo Generating aspects and building project
cd "%SRC_PATH%\SO_AJ_ITD_AddMainMethodToAllSubclasses_AJ"
rmdir /s /q bin .apt_generated
call "%ASPECTJ_HOME%\bin\ajc.bat" -8 -sourceroots src -d bin -s .apt_generated -cp "c:\Program Files\Java\AspectJ\lib\aspectjrt.jar";..\SO_AJ_ITD_AddMainMethodToAllSubclasses_APT\processor.jar
echo.
echo Running de.scrum_master.app.App
java -cp bin;"c:\Program Files\Java\AspectJ\lib\aspectjrt.jar" de.scrum_master.app.App
echo.
echo Running de.scrum_master.app.FooApp
java -cp bin;"c:\Program Files\Java\AspectJ\lib\aspectjrt.jar" de.scrum_master.app.FooApp
echo.
echo Running de.scrum_master.app.BarApp
java -cp bin;"c:\Program Files\Java\AspectJ\lib\aspectjrt.jar" de.scrum_master.app.BarApp
Console output: If you run the batch file, the output should look as follows:
Building annotation processor
Manifest wurde hinzugefügt
Eintrag META-INF/ wird ignoriert
META-INF/services/ wird hinzugefügt(ein = 0) (aus = 0)(0 % gespeichert)
META-INF/services/javax.annotation.processing.Processor wird hinzugefügt(ein = 43) (aus = 45)(-4 % verkleinert)
de/ wird hinzugefügt(ein = 0) (aus = 0)(0 % gespeichert)
de/scrum_master/ wird hinzugefügt(ein = 0) (aus = 0)(0 % gespeichert)
de/scrum_master/app/ wird hinzugefügt(ein = 0) (aus = 0)(0 % gespeichert)
de/scrum_master/app/EntryPoint.class wird hinzugefügt(ein = 430) (aus = 253)(41 % verkleinert)
de/scrum_master/aspect/ wird hinzugefügt(ein = 0) (aus = 0)(0 % gespeichert)
de/scrum_master/aspect/EntryPointProcessor.class wird hinzugefügt(ein = 5782) (aus = 2617)(54 % verkleinert)
Generating aspects and building project
Generated aspect de.scrum_master.app.MainMethodAspect_App to advise de.scrum_master.app.App
Generated aspect de.scrum_master.app.MainMethodAspect_BarApp to advise de.scrum_master.app.BarApp
Generated aspect de.scrum_master.app.MainMethodAspect_FooApp to advise de.scrum_master.app.FooApp
Running de.scrum_master.app.App
Doing something
Running de.scrum_master.app.FooApp
Doing something
Doing foo
Running de.scrum_master.app.BarApp
Doing something
Doing bar
If you look at the files generated by the annotation processor under SO_AJ_ITD_AddMainMethodToAllSubclasses_AJ\.apt_generated, you will find three classes looking like this (I am showing just one of them as a sample):
package de.scrum_master.app;
public aspect MainMethodAspect_FooApp {
public static void FooApp.main(String[] args) {
FooApp fooApp = new FooApp();
fooApp.doSomething();
fooApp.doFoo();
}
}
Sorry for this lenghty answer, but other than creating a GitHub repo and just pointing there, I had to mention it all in order to make it reproducible.
Enjoy!

Left padding a string in pig

I would like to left pad a string data type field with 0-s. Is there any way to do that? I need to have fixed length (40) values.
thanks in advance,
Clairvoyant
The number of zeros needs to be generate dynamically based on the length of the remaining string, so i don't think its possible in native pig.
This is very much possible in UDF.
input.txt
11111
222222222
33
org.apache.hadoop.util.NativeCodeLoader
apachepig
PigScript:
REGISTER leftformat.jar;
A = LOAD 'input.txt' USING PigStorage() AS(f1:chararray);
B = FOREACH A GENERATE format.LEFTPAD(f1);
DUMP B;
Output:
(0000000000000000000000000000000000011111)
(0000000000000000000000000000000222222222)
(0000000000000000000000000000000000000033)
(0org.apache.hadoop.util.NativeCodeLoader)
(0000000000000000000000000000000apachepig)
UDF code: The below java class file is compiled and generated as leftformat.jar
LEFTPAD.java
package format;
import java.io.IOException;
import org.apache.commons.lang.StringUtils;
import org.apache.pig.EvalFunc;
import org.apache.pig.data.Tuple;
public class LEFTPAD extends EvalFunc<String> {
#Override
public String exec(Tuple arg) throws IOException {
try
{
String input = (String)arg.get(0);
return StringUtils.leftPad(input, 40, "0");
}
catch(Exception e)
{
throw new IOException("Caught exception while processing the input row ", e);
}
}
}
UPDATE:
1.Download 4 jar files from the below link(apache-commons-lang.jar,piggybank.jar, pig-0.11.0.jar and hadoop-common-2.6.0-cdh5.4.5)
http://www.java2s.com/Code/Jar/a/Downloadapachecommonslangjar.htm
http://www.java2s.com/Code/Jar/p/Downloadpiggybankjar.htm
http://www.java2s.com/Code/Jar/p/Downloadpig0110jar.htm
2. Set all the 3 jar files to your class path
>> export CLASSPATH=/tmp/pig-0.11.1.jar:/tmp/piggybank.jar:/tmp/apache-commons-lang.jar
3. Create directory name format
>>mkdir format
4. Compile your LEFTPAD.java and make sure all the three jars are included in the class path otherwise compilation issue will come
>>javac LEFTPAD.java
5. Move the class file to format folder
>>mv LEFTPAD.class format
6. Create jar file name leftformat.jar
>>jar -cf leftformat.jar format/
7. jar file will be created, include into your pig script
Example from command line:
$ mkdir format
$ javac LEFTPAD.java
$ mv LEFTPAD.class format/
$ jar -cf leftformat.jar format/
$ ls
LEFTPAD.java format input.txt leftformat.jar script.pig

transfer command line arguments from java to jython / optparse

I want to make a jar file from a python package. I am using the jython-compile-maven-plugin with maven. The tricky part seems to be the handling of arguments. The receiving python package uses optparse which works fine on the python side but I have difficulties to provide the parameters via java / jython.
I got an error about missing arguments. Now I tried to provide the arguments to main() but it doesn't expect any.
This is how I call into the jar:
java -jar target/metrics-0.2.0-jar-with-dependencies.jar -f sample.txt --format csv -q
Java started
5 Arguments: -f, sample.txt, --format, csv, -q,
Exception in thread "main" javax.script.ScriptException: TypeError: main() takes no arguments (1 given) in <script> at line number 1
Any ideas on how to provide the args properly?
here is my InitJython.java:
package org.testingsoftware.metrics;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import org.apache.commons.lang.StringUtils;
public class InitJython {
public static void main(String[] args) throws ScriptException {
System.out.println("Java started");
System.out.print(args.length + " Arguments: ");
for (String s : args) {
System.out.print(s);
System.out.print(", ");
}
System.out.println();
ScriptEngine engine = new ScriptEngineManager().getEngineByName("python");
// c.exec("try:\n from metrics.metrics import main\n main()\nexcept SystemExit:\n pass");
engine.eval("from metrics.metrics import main");
engine.eval("main('" + StringUtils.join(args, " ") + "')");
System.out.println("Java exiting");
}
public void run() throws ScriptException {
}
}
This line,
engine.eval("main('" + StringUtils.join(args, " ") + "')");
evaluates to
engine.eval("main('-f sample.txt --format csv -q')");
This means that the main() Python function will receive one argument ("1 given", as it says in the error message).
In order to make it work, you could have a main() that looks something like this:
def main(arg):
# Split 'arg' to get the arguments that were given to InitJython
# on the command line as a list of strings
args = arg.split()
parser = OptionParser()
parser.add_option("-f", dest="filename",
help="read from FILENAME")
...
...
(opts, args) = parser.parse_args(args)

Doxygen - Generating Dynamic Groups with an Alias Command with a parameter

I'm looking to create a group hierarchy automatically, by having some kind of Alias command. E.g. I want the groups
Extension Methods
String Extensions
Stream Extensions
...
to be created with doxygen comments such as
/** Documentation for the method
* \extension{string}
*/
public void ExtensionMethod(this string str){
...
}
Where \extension{string} would map to something like
\addtogroup stringExtensions string Extensions
\ingroup ExtnMethods
Unfortunately this means that all the documentation written for the method gets associated with the group instead.
The closest I've got is that if you have something like
/** \addtogroup stringExtensions string Extensions
* \ingroup ExtnMethods
* \#{
* \#}
*/
/** \ingroup stringExtensions
* Documentation for the method
*/
public void ExtensionMethod(this string str){
...
}
it would work, but this needs the 2 separate comment blocks and I can't find any way to do that using an Alias.
I know that something can probably be achieved with an inputfilter - but I'm hoping something far simpler can be achieved.
I've found an answer using inputfilters that was neater than I first supposed - parse the entire file looking for \extension{...}, replacing it with an appropriate \ingroup command, and then append the desired \addgroup commands at the bottom of the file.
This can then be run as an inputfilter
The following is a python script that does this. Note that it doesn't check that what it's replacing is actually within a doxygen comment, but it's good enough for my purposes.
#!python
import sys, re
if(len(sys.argv) != 2):
print "Need exactly one argument, the file to filter"
exit(1)
extnFinder = re.compile("\\\\extension{(\w+)}")
extnTypes = set();
filename = sys.argv[1]
fileIn = open(filename, "r")
line = fileIn.readline()
def extnSub(matchobj):
extnTypes.add(matchobj.group(1))
return "\ingroup %(extn)sExtensions" % {'extn':matchobj.group(1)}
while line:
matches = extnFinder.findall(line)
sys.stdout.write(re.sub(extnFinder,extnSub,line))
line = fileIn.readline()
for extn in extnTypes:
print "\n\n/**\\addtogroup %(extn)sExtensions %(extn)s Extensions\n\\ingroup ExtnMethods\n */\n" % {'extn':extn}