How to plug custom distances with ELKI? - java

I've already read the tutorial at ELKI documentation ( http://elki.dbs.ifi.lmu.de/wiki/Tutorial/DistanceFunctions ).
Unfortunately, I'm not grasping how to plug the generated .class with MiniGUI (or bash script for the provided .jar). How it can be done?
Ps: I know it sounds absolutely noob, but when I try to "type" the class name, as suggested, I get the error "The following parameters could not be processed: HammingDistance", for example.

ELKI will load classes via the standard Java Classloader. Therefore, they must be on the class path or they cannot be loaded. An example call (assuming your classes are in the bin folder) is java -cp elki.jar:bin/ de.lmu.ifi.dbs.elki.application.ELKILauncher
Parameters are interpreted as follows:
If there is a class with this name (including the package name!) it is used.
Otherwise, ELKI tries prepending the package name of the expected interface. Which enables shortcut names.
Otherwise, known classes (from the service files) are checked for aliases. For example, the Euclidean distance has an alias name of l2, Manhattan has an alias l1.
The class must have a parameterless public constructor or a inner public static class Parameterizer.
Input assistance is built as follows:
.jar files on the classpath are checked for service files in META-INF/elki/<interface>
folders on the classpath put you in development mode, where a recursive list is performed and all .class files are inspected. This is much slower, but removes the need to edit the service files. Discovered classes show up below the ones listed in the service file.
Furthermore, the package de.lmu.ifi.dbs.elki.application.internal includes classes that will inspect everything on your classpath, and will report e.g. classes that do not have a parameterless public constructor, or a inner public static class Parameterizer.

Related

Controlling the loading of Java class in CLASSPATH

I am trying to apply patch using classpath approach, I mean I am adding modified class files as jar file, and while classes are getting loaded new version of classes are loaded. Therefore application is patched without changing original jar file.
The following classpath definition works fine;
java -cp patch/patch.jar;bin/ com.test.PatchClasspath
but when order of lib classes are changed it does not work.(as usual)
java -cp bin/;patch/patch.jar com.test.PatchClasspath
I would like to know is there a JVM parameter which indicates the lib loading order?
EDITED:
I amd modifying Util->print() method to verify patch is applied.
package com.test;
public class PatchClasspath {
public static void main(String[] args) {
Util util = new Util();
util.print();
}
}
package com.test;
public class Util {
public void print(){
System.out.println("Version-1");
}
}
Thanks.
There is no such parameter indicate the lib loading order in JVM (I believe), however, the java -classpath option itself will determine the class loading order base on the paths you put.
JDK document explain this:
http://docs.oracle.com/javase/1.4.2/docs/tooldocs/windows/classpath.html
Specification order
The order in which you specify multiple class path entries is important. The Java interpreter will look for classes in the directories in the order they appear in the class path variable. In the example above, the Java interpreter will first look for a needed class in the directory C:\java\MyClasses. Only if it doesn't find a class with the proper name in that directory will the interpreter look in the C:\java\OtherClasses directory.
Try -verbose:class, this will show you all the loaded classes, in which order they were loaded and from which jar they were loaded.
To control the order of classes loaded, you can modify the order of jars in your classpath, using the java -cp. I do not think there is a way howto control the order of classes being loaded from a specific jar.
To verify that the patch is applied, a simple/dummy solution is to add a static field with the System.out.println(""). For Example:
static {
System.out.println("[DBG] : My Patch v1.0 is loaded.");
}

Best way to override MATLAB's default static javaclasspath

MATLAB is configured to search its static java class path before searching the user-modifiable dynamic path. Unfortunately, the static path contains quite a number of very old public libraries, so if you are trying to use a new version you may end up loading the wrong implementation and get errors.
For instance, the static path contains an old copy of the google-collections.jar, which has long been supplanted by Google's guava library and which has some of the same class names (e.g. com.google.common.base.Objects). As a result, if you invoke a Guava method that uses a newer method of one of such a class, you will end up getting surprising NoSuchMethodErrors because the google-collections jar is found first.
As of R2012b, MATLAB lets you specify additional jars to add to the static path by putting a javaclasspath.txt file in your preferences folder, but that adds jars to the end of the path, and doesn't let you override jars that are built into MATLAB.
So what is the best way around this?
I got an official response from Mathworks:
As of MATLAB R2013a (also in R2012b), classes can be added to the front of the static Java class path by including the following line in javaclasspath.txt:
<before>
Any directory that is after this line in javaclasspath.txt will be added to the front of the static Java class path. This is an undocumented use of javaclasspath.txt as of R2013a.
But overall in MATLAB, the ability to add classes to the front of the static Java classpath is not available through javaclasspath.txt in MATLAB 8.0 (R2012b).
MATLAB searches for classpath.txt in the following order:
In the startup directory. As of MATLAB 8.0 (R2012b) a warning will be shown if the file is found there and it will be ignored.
In the first directory on the MATLABPATH environment variable. (This environment variable is used in the bin/matlab shell script on Linux and in general is not used by the end-user).
In the toolbox/local directory.
Although the MATLABPATH environment variable of point 2 is normally not used by end-users we can use it in a workaround to allow reading a custom classpath.txt outside of the toolbox/local directory.
On Windows:
You will need to create the MATLABPATH environment variable. The first directory on it should be your directory with the custom classpath.txt AND you will also need to add the toolbox\local directory as second option. So from a cmd prompt you could do:
set MATLABPATH=c:\Users\user\Documents\myMATLABClasspath;c:\Program Files\MATLAB\R2012b
\toolbox\local
matlab.exe
One hack that appears to work is to add the jar to the top of the classpath.txt file that can be found in your MATLAB installations toolbox/local folder. Unfortunately, this is automatically generated and may get rewritten at some unspecified time, such as when you install new toolboxes, so this approach would require you to have some way to notice when this happens and reapply the hack.
If you're distributing a jar that's intended to be used with matlab, it may be better to use proguard as described at http://code.google.com/p/guava-libraries/wiki/UsingProGuardWithGuava.
If you specify that all of your classes and their (public) fields and methods are to be preserved and include guava as a program jar (not a library), then it will rename all of guava's methods and update your compiled bytecode to reference the new names.
It seems a bit hackish, but depending on the audience, it may be significantly easier than teaching your users about static vs. dynamic classpath, and it won't break any matlab code that depends on the old behavior.
Instead of obfuscating the package as suggested by #user2443532, I have found it easier to "shade" the conflicting package instead of obfuscating it - unless you actually need obfuscation. One easy way to do this is to build your package using Maven and use the maven-shade-plugin. Internal calls are modified automatically, so you don't need to modify any of the Java code.
Direct calls from Matlab will need to be modified - for example, calls to com.opensource.Class become shaded.com.opensource.Class.
For more info on shading, see What is the maven-shade-plugin used for, and why would you want to relocate Java packages?

JAVA Type safety between two class at run time

I have two .jar files having same package structure and same class name.
Eg. math.jar and state.jar
package structure is com.myorg.common
and both jars having class called Util
Now, When i use the class in program...Object of which class will be created at run time?
and what if i wanted to create an object of specific class? (that is from math.jar)
It will depend on the order in which the jar files appear in the classpath. I believe the one that appears first in the classpath will be used. Any one classloader can only have a single class with a particular fully-qualified name.
Basically, this is a really bad idea - don't have the same class in the same package in multiple places; it's just asking for trouble.

Two classes with same name in classpath

If I have two classes with same name say Matcher.java in two different jar in my classpath which one will be picked up by JVM , is there anyway I can suggest JVM to pick a specific one ?
Quoting Oracle:
Specification order
The order in which you specify multiple class path entries is
important. The Java interpreter will look for classes in the
directories in the order they appear in the class path variable. In
the example above, the Java interpreter will first look for a needed
class in the directory C:\java\MyClasses. Only if it doesn't find a
class with the proper name in that directory will the interpreter look
in the C:\java\OtherClasses directory.
The example mentioned:
C:> java -classpath C:\java\MyClasses;C:\java\OtherClasses ...
So yes, it will load the one appears in the classpath that specified first.
The first one found in the classpath. ie, the first jar containing your class will be used.
You can't control it from within the JVM, but you can control the classpath - make sure the one you want is listed/found first in the classpath.
there is a way for you to specify where the class should be picked from.. you can create your own class loader which would load classes according to your requirement.
you can use your class loaded in 2 ways
Pass it as a parameter to jvm (java -Djava.system.class.loader
=com.somepackage.YourCustomClassLoader com.somepackage.YourMainClass)
Use the class loader programatically to load a specific class (refer the links provided).
here are some useful links on class loading
Oracle - How to write your own class loader
A very nice post on writing custom class loader
Use the fully qualified path of the class when using it. But if you mean the class with the same name also has the same package - fix the class-path.

Java: How to communicate between an annotation processor and another project?

I have an own annotation processor (let's call it MyProcessor) and a project (let's call it MyProject) which uses the processor by
passing -processor to javac.
Now I need MyProcessor to produce some output and make it available for MyProject.
I have following options (and problems):
Let MyProcessor write a file to the path, specified by the property user.dir.
Problem: from the point of view of MyProcessor, user.dir is always my home dir, not the path of MyProject.
Pass the current directory of MyProject to MyProcessor using javac's -A option.
Problem: It's an ugly hard-coded path: /some/path/to/MyProject/.
Let MyProcessor generate some source files, which then would be compiled by javac together with MyProject, so that MyProject can refer to this compiled class and retrieve data from it.
Problem: It's too complex for such an easy (?) task.
What other options are there?
Can someone please suggest, how to proceed?
Processor.init() method (which you've implemented) is invoked with ProcessingEnvironment as parameter which, in turn, has a getFiler() method returning a Filer instance.
You should be using the createResource() method of the Filer (assuming the output being generated is neither class nor source; otherwise use appropriate create method for that) and write your output to either class or source locations (former is probably preferable, but it depends on what you're doing). Both are overridable via command-line switches if need be, but are well-defined as they are to be used in a build process.

Categories