Build OpenCV with contrib modules and Java wrapper - java

I'm trying to build OpenCV on my Windows 7 machine. To include the contrib modules I have added the OPENCV_EXTRA_MODULES_PATH in CMake-gui. The opencv-300.jar and opencv-300.dll have been created but I can not find the Java classes to use the extra modules. Am I missing an option in the make configuration? Is it possible to use these extra modules from Java?

i've the same problem and i resolved in this way. I imagine that you had downloaded from contrib repo the specific version match with the opencv version if you want to build. So go in directory and enter, for example, face module directory; in this directory there is a file called CMakeLists.txt that you have to edit. This file should be like this:
set(the_description "Face recognition etc")
ocv_define_module(face opencv_core opencv_imgproc opencv_objdetect WRAP python)
# NOTE: objdetect module is needed for one of the samples
If you want to have the org.opencv.face package in your opencv-3xx.jar library you have to modify the 2nd line of the file in this way:
ocv_define_module(face opencv_core opencv_imgproc opencv_objdetect WRAP python java)
Then you have to compile opencv as depicted in the Readme.md of the contrib repo https://github.com/itseez/opencv_contrib
Obviously the same thing is valid for all the contrib modules if you want to add to your opencv-3xx.jar library.
I hope that this solution works for you, bye!

Related

Java, Maven: Need help embedding j2mod library into a java plugin

I need some help using j2mod, a java library for Modbus TCP/RTU into a plugin for Universal Robots.
Using the maven-bungle-plugin
What I have tried:
Including dependencies one by one (never ending dependency tree)
Using the tag to include the j2mod package in jar (program starts with a requires 'jSerialComm' error)
Using tag to include all dependencies of scope compile and runtime (program starts with a requires 'org.slf4.impl' error and I cant seem to figure out a way to adapt slf4j to log4j.)
I know from snooping around the polyscope simulator program's files. The simulator seems to use log4j-api-2.3.jar and a modified-log4j-core-1.11.6.jar.
Any insights on using j2mod or a similar java Modbus TCP/RTU library in an embedded system environment will me helpful.
Thank you

Gradle + Eclipse : use class from existing project in a new project

I know there are a lot of questions that seem similar. I have also spent a few hours getting to grips with Gradle multiprojects. But I still don't understand what the best course of action is here. Incidentally I am using Groovy as my coding language, but explanations referencing Java would be just as good.
I have developed an Eclipse Gradle project, "ProjectA", which in particular has a class, IndexManager, which is responsible for creating and opening and querying Lucene indices.
Now I am developing a new Eclipse Gradle project, "ProjectB", which would like to use the IndexManager class from ProjectA.
This doesn't really mean that I would like both projects to be part of a multiproject. I don't want to compile the latest version of ProjectA each time I compile ProjectB - instead I would like ProjectB to be dependent on a specific version of ProjectA's IndexManager. With the option of upgrading to a new version at some future point. I.e. much as with the sorts of dependencies you get from Maven or JCenter...
Both projects have the application plugin, so ProjectA produces an executable .jar file whose name incorporates the version. But currently this contains only the .class files, the resource files, and a file called MANIFEST.MF containing the line "Manifest-Version: 1.0". Obviously it doesn't contain any of the dependencies (e.g. Lucene jar files) needed by the .class files.
The application plugin also lets you produce a runnable distribution: this consists of an executable file (2 in fact, one for *nix/Cygwin, one for Windows), but also all the .jar dependencies needed to run it.
Could someone explain how I might accomplish the task of packaging up this class, IndexManager (or alternatively all the classes in ProjectA possibly), and then including it in my dependencies clause of ProjectB's build.gradle... and then using it in a given file (Groovy or Java) of ProjectB?
Or point to some tutorial about the best course of action?
One possible answer to this which I seem to have found, but find a bit unsatisfactory, appears to be to take the class which is to be used by multiple projects, here IndexManager, and put it in a Gradle project which is specifically designed to be a Groovy library. To this end, you can kick it off by creating the project directory and then:
$ gradle init --type groovy-library
... possible to do from the Cygwin prompt, but not from within Eclipse as far as I know. So you then have to import it into Eclipse. build.gradle in this library project then has to include the dependencies needed by IndexManager, in this case:
compile 'org.apache.lucene:lucene-analyzers-common:6.+'
compile 'org.apache.lucene:lucene-queryparser:6.+'
compile 'org.apache.lucene:lucene-highlighter:6.+'
compile 'commons-io:commons-io:2.6'
compile 'org.apache.poi:poi-ooxml:4.0.0'
compile 'ch.qos.logback:logback-classic:1.2.1'
After this, I ran gradle jar to create the .jar which contains this IndexManager class, initially without any fancy stuff in the manifest (e.g. name, version). And I put this .jar file in a dedicated local directory.
Then I created another Gradle project to use this .jar file, the critical dependency here being
compile files('D:/My Documents/software projects/misc/localJars/XGradleLibExp.jar' )
The file to use this class looks like this:
package core
import XGradleLibExp.IndexManager
class Test {
public static void main( args ) {
println "hello xxx"
Printer printer = new Printer()
IndexManager im = new IndexManager( printer )
def result = im.makeIndexFromDbaseTable()
println "call result $result"
}
}
class Printer {
def outPS = new PrintStream(System.out, true, 'UTF-8' )
}
... I had designed IndexManager to use an auxiliary class, which had a property outPS. Groovy duck-typing means you just have to supply anything with such a property and hopefully things work.
The above arrangement didn't run: although you can do build and installdist without errors, the attempt to execute the distributed executable fails because the above 6 compile dependency lines are not present in build.gradle of the "consumer" project. When you put them in this "consumer" Gradle project's build.gradle, it works.
No doubt you can add the version to the generated .jar file, and thus keep older versions for use with "consumer" projects. What I don't understand is how you might harness the mechanism which makes the downloading and use of the dependencies needed by the .jar as automatic as we are used to for things obtained from "real repositories".
PS in the course of my struggles today I seem to have found that Gradle's "maven-publish" plugin is not compatible with Gradle 5.+ (which I'm using). This may or may not be relevant: some people have talked of using a "local Maven repository". I have no idea whether this is the answer to my problem... Await input from an über-Gradle-geek... :)
You should be able to update the Eclipse model to reflect this project-to-project dependency. It looks something like this (in ProjectB's build.gradle):
apply plugin: 'eclipse'
eclipse {
classpath.file.whenMerged {
entries << new org.gradle.plugins.ide.eclipse.model.ProjectDependency('/ProjectA')
}
project.file.whenMerged {
// add a project reference, which should show up in /ProjectB/.project's <projects> element
}
}
These changes may be to the running data model, so they may not actually alter the .classpath and .project files. More info can be found here: https://docs.gradle.org/current/dsl/org.gradle.plugins.ide.eclipse.model.EclipseModel.html
This issue is discussed here: http://gradle.1045684.n5.nabble.com/Gradle-s-Eclipse-DSL-and-resolving-dependencies-to-workspace-projects-td4856525.html and a bug was opened but never resolved here: https://issues.gradle.org/browse/GRADLE-1014

Maven equivalent in .NET C#

Let's assume there are two Maven Java projects, A and B. A has a dependency on B. B is placed in remote Maven repository and also on GitHub.
In IntelliJ Idea IDE, I will open project A and also B (B is cloned from GitHub) in two separate windows.
Now, B has a class named Car. When I 'Ctrl+Left mouse button click' on class Car in project A, IDE switches me automatically to the source code in opened project B. Therefore I can comfortably work together on A and B.
How can I achieve same behaviour with .NET C# and Visual Studio?
The rough equivalent to Maven in the .NET ecosystem is NuGet. NuGet files can be created using the IDE or command-line tools such as dotnet pack or nuget pack. A NuGet file is just a regular .zip file with the .nupkg extension. These files can be hosted on http://www.nuget.org for the general public to consume, on a site such as http://www.myget.org, or on a private hosted NuGet server.
The NuGet tools also have the ability to create debug symbol packages that contain the source code files. The debug symbol packages can be hosted on public or private symbol servers and used in Visual Studio to step through the code, with the configuration options enabled in Visual Studio.
If you open project A in Visual Studio and automatic package restore is enabled and that project has a package reference to project B, when you build the project it will automatically download the NuGet file for project B, unpack it to your local NuGet cache, and use the assembly for project B in your project.
If Visual Studio is configured correctly to find a debug symbols package corresponding to the exact version of project B, it will allow the debugger to step through the code of project B.
AFAIK, opening the code file of project B and then setting a break point is not possible (someone leave a comment if this is wrong), you need to set a breakpoint in project A and then when you step into the line that calls/instantiates the Car class, Visual Studio will open up the code file so you can step through it.
Update 2023-01-15
Note that the above symbols documentation still works, but there is now a better way. If the author of a NuGet package configures Source Link and the code exists in a Git repository, an IDE can enable source stepping and the code files can be downloaded directly from the repository into the IDE's debugger. This means it is no longer necessary to package source files in the symbols package. This feature uses a Git commit hash to ensure that the source code matches the binary even if you upgrade the NuGet package later.
The symbols have also been updated to allow a .snupkg file by including <PropertyGroup><IncludeSymbols>true</IncludeSymbols><SymbolPackageFormat>snupkg</SymbolPackageFormat></PropertyGroup> in the project file. This new format can be uploaded directly to NuGet instead of having to use a 3rd party symbol or self hosted server for debugging.
Well, actually it is possible. But some MSBuild modification is necessary.
Preconditions:
use the new MSBuild format that was shiped with VS 2017
Step by step:
create a solution and add both projects
I assume project A has a package reference to project B and the nuget package names are the same as the project names
in the root directory of both projects, which is probably not part of any source control system, create a file with the name Directory.Build.targets with the following content:
true
<PropertyGroup>
<SolutionFileContent>$([System.IO.File]::ReadAllText($(SolutionPath)))</SolutionFileContent>
<SmartSolutionDir>$([System.IO.Path]::GetDirectoryName( $(SolutionPath) ))</SmartSolutionDir>
<RegexPattern>(?<="[PackageName]", ")(.*)(?=", ")</RegexPattern>
</PropertyGroup>
<ItemGroup>
<!-- Keep the identity of the packagereference -->
<SmartPackageReference Include="#(PackageReference)">
<PackageName>%(Identity)</PackageName>
<InSolution>$(SolutionFileContent.Contains('\%(Identity).csproj'))</InSolution>
</SmartPackageReference>
<!-- Filter them by mapping them to another itemGroup using the WithMetadataValue item function -->
<PackageInSolution Include="#(SmartPackageReference -> WithMetadataValue('InSolution', True) )">
<Pattern>$(RegexPattern.Replace('[PackageName]','%(PackageName)') )</Pattern>
<SmartPath>$([System.Text.RegularExpressions.Regex]::Match( '$(SolutionFileContent)', '%(Pattern)' ))</SmartPath>
</PackageInSolution>
<ProjectReference Include="#(PackageInSolution -> '$(SmartSolutionDir)\%(SmartPath)' )"/>
<!-- Remove the package references that are now referenced as projects -->
<PackageReference Remove="#(PackageInSolution -> '%(PackageName)' )"/>
</ItemGroup>
</When>
What happens here, is that all package references are automatically dynamically replaced with project references, when they are contained in the currently opened solution.
For further information, i have posted that solution also in a MSBuild github issue:
https://github.com/dotnet/sdk/issues/1151

How to keep two android support version from project?

I am developing an application that use aFileChooser library (github)
and have some trouble. This is the size of android-support-v4.jar file in each project:
MyProject: 973kb
appcompat_v7: 973kb (same as above)
aFileChooser: 607kb (may be an old version)
When I include appcompat_v7 and aFileChooser project into MyProject project, there is a config, and I replace a android-support-v4 in aFileChooser with a new one from MyProject (973k). It works
But, when i debug my application, sometime a get an error "Could not find class XXX..." like this:
So, perhap some class has been deprecated and removed in new version, but the library (aFileChooser) still used them. Then I must:
Change all deprecated method and class in the library, but It will need
spend much time to do.
I reuse an old version (607kb) and rename it to
android-support-v4-old.jar, but it doesn't work. Eclipse still
check multiple define:
Multiple dex files define
Landroid/support/v4/accessibilityservice/AccessibilityServiceInfoCompat$AccessibilityServiceInfoVersionImpl;
So, is there any solution that still use the old version. I think replace 2 new android-support-v4.jar with an old one is not recommended?

Using MessagePack with Android

Has someone tried to use MessagePack with an Android app?
Is it possible? I have tried to use the Jar from msgpack-java and received the following Exception:
Caused by: java.lang.ExceptionInInitializerError
at org.msgpack.Packer.pack(Packer.java:532)
at org.msgpack.MessagePack.pack(MessagePack.java:31)
... 15 more
Caused by: java.lang.ExceptionInInitializerError
at org.msgpack.template.TemplateRegistry.<clinit>(TemplateRegistry.java:38)
... 17 more
Caused by: java.lang.VerifyError: org.msgpack.template.BeansFieldEntryReader
at org.msgpack.template.builder.BeansTemplateBuilder.<init (BeansTemplateBuilder.java:42)
at org.msgpack.template.builder.BuilderSelectorRegistry.initForJava(BuilderSelectorRegistry.java:73)
at org.msgpack.template.builder.BuilderSelectorRegistry.<clinit>(BuilderSelectorRegistry.java:38)
... 18 more
The code that I use is very simple
PrintWriter out = new PrintWriter(socket.getOutputStream());
Message msg = new Message();
msg.body = "asdasdasd";
msg.from = "qwe";
msg.to = "ttt";
byte[] bytes = MessagePack.pack(msg);
out.print(bytes);
out.flush();
I have javassist.jar, msgpack-0.5.2.jar, slf4j-api-1.6.2.jar and slf4j-jdk14-1.6.2.jar in my lib directory.
In my server application this code works fine with the same libraries.
(Hopefully) FINAL UPDATE
msgpack : 0.6.8 works on Android without any problems
msgpack-rpc : 0.7.0 works on Android with one caveat.
Specifically, you need to add the following to onCreate for API Level 8 (Android 2.2.1), and possibly lower:
java.lang.System.setProperty("java.net.preferIPv4Stack", "true");
java.lang.System.setProperty("java.net.preferIPv6Addresses", "false");
due to this bug.
If you want to see a simple example, here's a pair of projects set up for this purpose:
https://github.com/mikkoz/msgpack-android-test-server/tree/master/msgpack-android-test-server
https://github.com/mikkoz/msgpack-android-test-client/tree/master/msgpack-android-test-client
Previous Versions
UPDATE: as of 0.6.7 msgpack should be compatible with Android (there is a small dependency exclusion issue). Check the text below for msgpack-rpc (which also might be adapted in the future).
NOTE: If you're also using msgpack-rpc, you need to do the following steps:
Download the msgpack-rpc source from git://github.com/msgpack/msgpack-rpc.git (specifically, the "java" folder).
Change the main msgpack artifact version to the one you've built.
In org.msgpack.rpc.loop.netty.NettyEventLoop, change the NioClientSocketChannelFactory to OioClientSocketChannelFactory(getWorkerExecutor()).
Build the MessagePack-RPC in the same way as in the case of the main MessagePack JAR (see Step 11 above).
The NettyEventLoop replacement is due to this issue:
http://markmail.org/message/ypa3nrr64kzsyfsa .
Important: I've only tested synchronous communication. Asynchronous might not work.
And here's the reason for msgpack not working with Android prior to 0.6.7:
The reason for the error is that MessagePack uses several java.beans classes that are not included in the Android SDK. You're probably using the MessagePackBeans annotation.
This is a similar problem to the one described here, for which the general solution is outlined here. Unfortunately, in our case it requires a rebuild of msgpack. Here's what I did (you can almost certainly skip Steps 5 and 8, but I haven't tried it that way) :
Download the MessagePack source from https://github.com/msgpack/msgpack-java.git.
Import the MessagePack source as a project in your IDE.
Download the Apache Harmony source for the relevant packages from http://svn.apache.org/repos/asf/harmony/enhanced/java/trunk/classlib/modules/beans/src/main/java .
Copy these packages into your MessagePack project's src/main/java folder:
java.beans
java.beans.beancontext
org.apache.harmony.beans
org.apache.harmony.beans.internal.nls
In your MessagePack project, remove the following classes:
PropertyChangeListener
IndexedPropertyChangeEvent
PropertyChangeEvent
PropertyChangeListenerProxy
PropertyChangeSupport
Rename the java.beans packages to something different, e.g. custom.beans .
Change all java.beans references to the renamed ID, so again e.g. custom.beans. This applies especially to BeansFieldEntryReader (this class is the reason for the original error).
Change the custom.beans references for the five classes you removed in Step 5 back to java.beans.
In the org.apache.harmony.beans.internal.nls.Messages class, comment out the method setLocale, and remove the imports associated with it.
Remove all classes that still have errors, except Encoder. In that class, comment out all references to the classes you've removed. You should now have an error-free project.
Build the MessagePack JAR:
If you're using Maven, change the version in the pom.xml to something unique, run Maven build with the install goal, then add the dependency in your Android project with that version.
If you're not using Maven, you have to run the jar goal for Ant with the included build.xml. Replace the msgpack JAR in your Android project with this one.
If you're publishing your app, remember to include the relevant legal notice for Apache Harmony. It's an Apache License, just like MessagePack.
That should do it. Using your example code, and my own data class, I was successfully able to pack and unpack data.
The entire renaming ritual is due to the fact that the DEX compiler complains about java.* package naming.
There is a critical msgpack bug saying data packed with msgpack will get corrupted on the Dalvik VM. http://jira.msgpack.org/browse/MSGPACK-51
There is an ongoing effort by #TheTerribleSwiftTomato and the MessagePack core team to get MessagePack working on Android, please see the related GitHub issue. The fix mentioned in #TheTerribleSwiftTomato's answer is to be found here.
Update
I've managed to get it at least running on Android by (painstakingly) adding all the necessary javassist Classes which are currently required for the build to succeed. An extra 600KB gain in size, yet at least it seems to work. All in all, it appears to be working to some extent on Android, eventually check out the lesser-known resources about Message Pack such as its User Group and its Wiki for more information.
On a side-note, be sure to use a HTTP Request Library (such as LoopJ's Android Async HTTP or Apache's HttpClient) which can handle binary data.
Last but not least you can ping me if there is interest in this jar which makes MessagePack seemingly work on Android – credits go out of course to #TheTerribleSwiftTomato who supplied the fix above!
I suggest you write this in the main proguard-rules file-
-dontwarn org.msgpack.**
-keep class org.msgpack.** { *; }

Categories