I'm using RDF4J as I got caught by the advertised implementation of GEOSPARQL (which I didn't find in other RDF frameworks). I followed basic guides and tutorial, but unfortunately I haven't been able to perform basically any of the advertised queries.
I read and followed all the documentation at http://docs.rdf4j.org/programming/#_geosparql, and all the examples at http://graphdb.ontotext.com/documentation/standard/geosparql-support.html, and at https://portal.opengeospatial.org/files/?artifact_id=47664. The only spatial function that seemed to work in a SPARQL query is the geof:distance, all the others do not produce any results.
So I ultimately dug into the code in the package org.eclipse.rdf4j.query.algebra.evaluation.function.geosparql to kind of understand that there are some classes and interfaces that I should probably implements and extends, e.g. SpatialAlgebra, SpatialSupport, SpatialSupportInitializer. It looks like many of the function are not completely (or partially) implemented in the spatial logic. Apparently, there is a DefaultSpatialAlgebra which returns a lot of notSupported. Anyway, it's quite a mess (and undocumented) understanding what's the right procedure to have GEOSPARQL working properly. They only say that you can implement your own SpatialSupportInitializer, but how to use it afterwards is a mystery.
From the documentation, apparently there's also a way by using other SAILs, but again, nothing is clear about that.
Can anybody provide me with some guidance, or at least a snippet of code where it is shown how to actually pass to the engine a SpatialAlgebra or SpatialSupport or SpatialSupportInitializer, which is not the default one? Or is there any already existing SAIL which implements all these methods, and how can I use it? Thanks.
PS: I'm actually relying on the 2.4.0 M2 version of RDF4J, which doesn't seem to have the org.eclipse.rdf4j.query.algebra.evaluation.function.geosparql package inside (which I imported manually). I tried also with version 2.3.1, but I had the same issue.
Update Since RDF4J 2.4.0-M3, GeoSPARQL function support is a lot more comprehensive. The improved documentation gives a full list of all supported functions, as well as, hopefully, a better explanation on how to get started with GeoSPARQL. The short and sweet of it is that all you need to do is add this maven module:
<dependency>
<groupId>org.eclipse.rdf4j</groupId>
<artifactId>rdf4j-queryalgebra-geosparql</artifactId>
<version>2.4.0-M3</version>
</dependency>
and you're good to go to use GeoSPARQL on any kind of RDF4J repository.
There are several other GeoSPARQL functions supported by RDF4J out of the box: apart from distance, union, intersection, symDifference, difference, convexHull, boundary, envelope, and getSRID are also at a minimum supported. sfContains is currently not part of the default set, unfortunately. This is mostly due to a licensing issue RDF4J had with a previous version of the JTS library (required for polygon support). However, more recent JTS releases are done as part of the LocationTech project, and those license issues have cleared up, so we should hopefully be able to extend this in the near future (there's an issue tracking this at https://github.com/eclipse/rdf4j-storage/issues/89).
In the meantime you will indeed need to create your own `SpatialAlgebra` class, which you can add to RDF4J by means of a `SpatialSupportInitializer`. This is a bit of a workaround hack, but you should create a class with `org.eclipse.rdf4j.query.algebra.evaluation.function.geosparql.SpatialSupportInitializer` as its fully-qualified name, and make sure that it extends the `org.eclipse.rdf4j.query.algebra.evaluation.function.geosparql.SpatialSupport` abstract class, overriding its `getSpatialContext` and `getSpatialAlgebra` methods to provide your custom variants. Add to your classpath and restart, RDF4J will pick this up and use your `SpatialAlgebra` implementation instead of its own.
The bottom line is: this is all very beta. To be frank, if you think you could handle implementing additional GeoSPARQL functions using the workaround I mentioned above, then we would love to have your input (and if possible also your help) in actually adding this to RDF4J itself.
Related
Most of the time, I don't like Javascript and would prefer strict and compiled languages like Scala, Java, Haskell...
However, one thing that can be nice with Javascript is to be able to easily change code of external dependencies. For exemple, if you have a bug and you think it's one of your dependency library you can easily hack around and swap a library method by your own override and check if it's better. You can even add methods to Array ou String prototypes and things like that... One could even go to node_modules and alter the library code here temporarily if he wants to.
In the JVM world this seems to me like an heavy process to just get started:
Clone the dependency sources
Hack it
Compile it
Publish it to some local maven/ivy repository
Integrate the fixed version in your project
This is a pain, I just don't want to do that more than once in a year
Today I was trying to fix a bug in my app, and the lib did not provide me enough information. I would have loved to just be able to put a Logger on one line of that lib to have better insight of what was happening but instead I tried to hack with the debugger with no success (the bug was not reproductible on my computer anyway...)
Isn't there any simple alternative for rapidly altering the code of a dependency?
I would be interested in any solution for Scala, Java, Clojure or any other JVM language.
I'm not looking for a production-deployable solution, just a quick solution to use locally and eventually deployable on a test env.
Edit: I'm talking about library internals that are not intended to be modified by the library author. Please assume that the class to change is final, not replaceable by library configuration, and not injectable by any way into the library.
In Clojure you can re-bind vars, also from other namespaces, by using intern. So as long as the code you want to alter is Clojure code, that's a possible way to monkeypatch.
(intern 'user 'inc dec)
(inc 1)
=> 0
This is not something to do lightly though, since it can and will lead to problems with other code not expecting this behavior. It can be handy to use during development to temporarily fix edge cases or bugs in other libraries, but don't use it in published libraries or production code.
Best to simply fork and fix these libraries, and send a pull request to have it fixed in the original library.
When you're writing a library yourself that you expect people need to extend or overload, implement it in Clojure protocols, where these changes can be restricted to the extending/overloading namespaces only.
I disagree that AspectJ is difficult to use, it, or another bytecode manipulation library is your only realistic alternative.
Load-time weaving is a definite way around this issue. Depending on how you're using the class in question you might even be able to use a mocking library to achieve the same results, but something like AspectJ, which is specifically designed for augmentation and manipulation, would likely be the easiest.
I have created a library which supports an application, however in the newest version of the application the developer has changed the structure without changing the class names.
So version 1 of the application has classX in package A but version 2 has classX in package B. How can I develop my library in a way which allows supporting both of these in the same build?
Edit: My library is dependent on the application, not the other way around.
That is a bad decision, if you still want to make it work you need to provide skeleton classes with old structure and delegate calls to new version of class but it would get very dirty
better to not provide backward compatibility if you are firm with the renaming decision
Short answer: You can't.
Real answer: Your library should be able to exist independently of any application that uses it. The purpose of a library is to provide a set of reusable, modular code that you can use in any application. If your library is directly dependent on application classes, then it seems like a redesign should be seriously considered, as your dependencies are backwards. For example, have A.classX and B.classX both implement some interface (or extend some class) that your library provides, then have the application pass instances of those objects, or Class's for those objects, to the library.
If your "library" can't be designed this way then consider integrating it into application code, making it a direct part of the application, and come up with a better team workflow for you, the other developer, and others to work on the same project together.
Quick fix answer: Do not provide backward compatibility, as Jigar Joshi states in his answer.
Bad answer: You could hack a fragile solution together with reflection if you really had to. But please note that the "real answer" is going to last in the long run. You are already seeing the issues with the design you have currently chosen (hence your question), and a reflection based solution isn't going to prevent that from happening again (or even be reliable).
I have a database-heavy distributable java application that's currently only 400k. We need improved database query building as well as support for a few specific database dialects.
jOOQ has to be shaded into our JAR and it balloons it up to 1.6MB, even when using the minimizeJar elements for shade.
Is there a way I can do a custom build or strip out the components of jOOQ that we have no use for right now? Dialects, non insert/select/delete query classes, other features we don't need?
I thought about trying to identify every imported class that we're using and setting maven to only shade those, but I'd also need to handle classes jOOQ uses internally and I don't know how reliant jOOQ is on everything.
If I could strip it down to a few hundred k, I'd be sold on continuing to use it.
jOOQ is a domain-specific language implemented according to the principles explained here:
http://blog.jooq.org/2012/01/05/the-java-fluent-api-designer-crash-course/
This means that every "production" or "primary" from the DSL specification generates a Java interface with all the overhead this may generate in the class loader. Additionally, since jOOQ 3.0, record and row types with degree 1-22 were introduced (e.g. org.jooq.Row1, org.jooq.Row2, ... org.jooq.Row22). All of these elements are part of the API, which probably cannot be stripped down any further.
Of course, you can try to manually strip down the jOOQ API and implementation, removing all the row types from it. Another entire statement that you might not need is the MERGE statement, which also has an extensive API. Then, there are the tools packages, which aren't strictly needed, specifically:
org.jooq.tools.csv
org.jooq.tools.json
org.jooq.types
org.jooq.util.[dialect]
Also, you can try to remove a couple of classes from the org.jooq.impl package. The class names should be fairly straight-forward to help you decide whether something is needed.
It would be interesting to see how far you get with such measures. This might be useful for Android users, too.
I am maintaining some code the implements a customized Look and Feel in Java. While doing a recent upgrade of Java version (for other reasons) I found that the Look and feel broke due to a field not found on
sun.swing.SwingUtilities2.BASICMENUITEMUI_MAX_TEXT_OFFSET;
This is in a class that is closely based on BasicMenuItemUI.layoutMenuItem() circa Java 6u02 (here's the source). I have found that Oracle have re-factored their code to include a MenuItemLayoutHelper in the new target version I am using, Java 6u31.
I could just use the MenuItemLayoutHelper but that doesn't solve the problem it just puts it off until the next time the Java internals are changed around. Therefore, I have discounted this as a solution.
I am after some advise on how to achieve a left to right layout similar to BasicMenuItemUI without needing to know the parents' maximum text offset (removing the bad dependency on sun.swing.SwingUtilities).
As albfan said, you can't. You either have to depend on the code, copy the class and use it in your program, not use it at all and use a third party library, or not use that feature.
Ok it may have been a while but I figured out I could just use my own constant instead of sun.swing.SwingUtilities2.BASICMENUITEMUI_MAX_TEXT_OFFSET as long as it was used consistently in the offending code. By no means an ideal solution.
On the upside bad imports from sun packages has gone into the coding rule checks.
This is for an Android application but I'm broadening the question to Java as I don't know how this is usually implemented.
Assuming you have a project that targets a specific SDK version. A new release of the SDK is backward incompatible and requires changing three lines in one class.
How is this managed in Java without duplicating any code(or by duplicating the least amount)?
I don't want to create two projects for only 3 lines that are different.
What I'm trying to achieve in the end is a single executable that'll work for both versions. In C/C++, you'd have a #define based on the version. How do I achieve the same thing in Java?
Edit: after reading the comments about the #define, I realized there were two issues I was merging into one:
So first issue is, how do I not
duplicate code ? What construct is there that is the equivalent of a
#define in C.
The second one is: is it possible
to bundle everything in the same
executable? (this is less of a
concern as the first one).
It depends heavily on the incompatibility. If it is simply behavior, you can check the java.version system property and branch the code accordingly (for three lines, something as simple as an if statement).
If, however, it is a lack of a class or something similar that will throw an error when the class is loaded or when the code gets closer to execution (not necessarily something you can void reasonably by checking before calling), then the solution gets a lot harder. The notion of having a separate version is the cleanest from a code point of view, but it does mean you have to distribute two versions.
Another solution is reflection. Don't reference the class directly, call it via reflection (test for the methods or classes to determine what environment you are currently running in and execute the methods). This is probably the "official" approach in that reflection exists to deal with classes that you don't have or don't know you will have at compile time. It is just being applied to libraries within the JDK. It gets very ugly very fast, however. For three lines of code, it's ok, but doing anything extensive is going to get bad.
The last thing I can think of is to write common denominator code - that is code that gets the job done in both, finding another way to do it that doesn't trigger the problematic class or method.
I would isolate the code that needs to be different in a separate class (or multiple classes if necessary), and include / exclude them when building the project for the different versions.
So i would have like src/java/org/myproj/Foo.java which is the common stuff, and then oldversion/java/org/myproj/Bar.java and newversion/java/org/myproj/Bar.java which is the different implementations of the class that uses changed api.
Then I either compile "src/java and oldversion/java" or "src/java and newversion/java".
Possibly a similar situation, I had a method which wasn't available in the previous version of the JDK but if it was there I wanted to call it, I didn't want to force people to use the more recent version though. I used reflection to look for the method, if it was there I called it, if it wasn't I didn't.
Pretty hacky but might give you what you want.
Addressing Java in general, I see two primary approaches.
1). Refactor the specific code to its own library. Have different versions of that library. Effectively your app is creating an abstaction above the different SDKs. Heavyweight for 3 lines of code, but perhaps quite reasonable for larger scale problems.
2). Injection using annotation. Write your own annotation processor to manage the appropriate injection. More work, but maybe more fun.
Separate changing code in different classes with the same interface. Place classes in the same jar. Use factory design pattern to instantiate one or another class depending on SDK version.