I have been trying to validate a sample string which I read from a file. I want to check if the condition in the given string evaluates to true or false.
String Test = "( ((10>20) & (10>5)) & (7>9) ) | (123>45)";
How can I do that using Java. I have been trying to split the brackets and operators. Is there any easy way to solve this kind of textual expressions?
I have tried JSR.JAR but I'm getting
java.lang.NoClassDefFoundError: Failed resolution of: Lsun/misc/Service; at javax.script.ScriptEngineManager.initEngines(ScriptEngineManager.java:108)at javax.script.ScriptEngineManager.access$000(ScriptEngineManager.java:55)at javax.script.ScriptEngineManager$1.run(ScriptEngineManager.java:98)at java.security.AccessController.doPrivileged(AccessController.java:45)at javax.script.ScriptEngineManager.init(ScriptEngineManager.java:96)at javax.script.ScriptEngineManager.(ScriptEngineManager.java:69)
It seems that android does not provide the java scripting engine.
Possibly you could use a third party library instead:
AndroidJSCore
J2V8 (java wrapper built on top of googles V8 engine)
My project requires Java 1.6 for compilation and running. Now I have a requirement to make it working with Java 1.5 (from the marketing side). I want to replace method body (return type and arguments remain the same) to make it compiling with Java 1.5 without errors.
Details: I have an utility class called OS which encapsulates all OS-specific things. It has a method
public static void openFile(java.io.File file) throws java.io.IOException {
// open the file using java.awt.Desktop
...
}
to open files like with double-click (start Windows command or open Mac OS X command equivalent). Since it cannot be compiled with Java 1.5, I want to exclude it during compilation and replace by another method which calls run32dll for Windows or open for Mac OS X using Runtime.exec.
Question: How can I do that? Can annotations help here?
Note: I use ant, and I can make two java files OS4J5.java and OS4J6.java which will contain the OS class with the desired code for Java 1.5 and 1.6 and copy one of them to OS.java before compiling (or an ugly way - replace the content of OS.java conditionally depending on java version) but I don't want to do that, if there is another way.
Elaborating more: in C I could use ifdef, ifndef, in Python there is no compilation and I could check a feature using hasattr or something else, in Common Lisp I could use #+feature. Is there something similar for Java?
Found this post but it doesn't seem to be helpful.
Any help is greatly appreciated. kh.
Nope there isn't any support for conditional compilation in Java.
The usual plan is to hide the OS specific bits of your app behind an Interface and then detect the OS type at runtime and load the implementation using Class.forName(String).
In your case there no reason why you can't compile the both OS* (and infact your whole app) using Java 1.6 with -source 1.5 -target 1.5 then in a the factory method for getting hold of OS classes (which would now be an interface) detect that java.awt.Desktop
class is available and load the correct version.
Something like:
public interface OS {
void openFile(java.io.File file) throws java.io.IOException;
}
public class OSFactory {
public static OS create(){
try{
Class.forName("java.awt.Desktop");
return new OSJ6();
}catch(Exception e){
//fall back
return new OSJ5();
}
}
}
Hiding two implementation classes behind an interface like Gareth proposed is probably the best way to go.
That said, you can introduce a kind of conditional compilation using the replace task in ant build scripts. The trick is to use comments in your code which are opened/closed by a textual replacement just before compiling the source, like:
/*{{ Block visible when compiling for Java 6: IFDEF6
public static void openFile(java.io.File file) throws java.io.IOException {
// open the file using java.awt.Desktop
...
/*}} end of Java 6 code. */
/*{{ Block visible when compiling for Java 5: IFDEF5
// open the file using alternative methods
...
/*}} end of Java 5 code. */
now in ant, when you compile for Java 6, replace "IFDEF6" with "*/", giving:
/*{{ Block visible when compiling for Java 6: */
public static void openFile(java.io.File file) throws java.io.IOException {
// open the file using java.awt.Desktop
...
/*}} end of Java 6 code. */
/*{{ Block visible when compiling for Java 5, IFDEF5
public static void openFile(java.io.File file) throws java.io.IOException {
// open the file using alternative methods
...
/*}} end of Java 5 code. */
and when compiling for Java 5, replace "IFDEF5". Note that you need to be careful to use // comments inside the /*{{, /*}} blocks.
You can make the calls using reflection and compile the code with Java 5.
e.g.
Class clazz = Class.forName("java.package.ClassNotFoundInJavav5");
Method method = clazz.getMethod("methodNotFoundInJava5", Class1.class);
method.invoke(args1);
You can catch any exceptions and fall back to something which works on Java 5.
The Ant script introduced below gives nice and clean trick.
link: https://weblogs.java.net/blog/schaefa/archive/2005/01/how_to_do_condi.html
in example,
//[ifdef]
public byte[] getBytes(String parameterName)
throws SQLException {
...
}
//[enddef]
with Ant script
<filterset begintoken="//[" endtoken="]">
<filter token="ifdef" value="${ifdef.token}"/>
<filter token="enddef" value="${enddef.token}"/>
</filterset>
please go to link above for more detail.
In java 9 it's possible to create multi-release jar files. Essentially it means that you make multiple versions of the same java file.
When you compile them, you compile each version of the java file with the required jdk version. Next you need to pack them in a structure that looks like this:
+ com
+ mypackage
+ Main.class
+ Utils.class
+ META-INF
+ versions
+ 9
+ com
+ mypackage
+ Utils.class
In the example above, the main part of the code is compiled in java 8, but for java 9 there is an additional (but different) version of the Utils class.
When you run this code on the java 8 JVM it won't even check for classes in the META-INF folder. But in java 9 it will, and will find and use the more recent version of the class.
I'm not such a great Java expert, but it seems that conditional compilation in Java is supported and easy to do. Please read:
http://www.javapractices.com/topic/TopicAction.do?Id=64
Quoting the gist:
The conditional compilation practice is used to optionally remove chunks of code from the compiled version of a class. It uses the fact that compilers will ignore any unreachable branches of code.
To implement conditional compilation,
define a static final boolean value as a non-private member of some class
place code which is to be conditionally compiled in an if block which evaluates the boolean
set the value of the boolean to false to cause the compiler to ignore the if block; otherwise, keep its value as true
Of course this lets us to "compile out" chunks of code inside any method. To remove class members, methods or even entire classes (maybe leaving only a stub) you would still need a pre-processor.
if you don't want conditionally enabled code blocks in your application then a preprocessor is only way, you could take a look at java-comment-preprocessor which can be used for both maven and ant projects
p.s.
also I have made some example how to use preprocessing with Maven to build JEP-238 multi-version JAR without duplication of sources
Java Primitive Specializations Generator supports conditional compilation:
/* if Windows compilingFor */
start();
/* elif Mac compilingFor */
open();
/* endif */
This tool has Maven and Gradle plugins.
hi I have got similar problem when I have shared library between Java SDK abd Android and in both environments are used the graphics so basically my code must to work with both
java.awt.Graphics and android.graphics.Canvas,
but I don't want to duplicate almost any code.
My solution is to use wrapper, so I access to graphisc API indirectl way, and
I can change a couple of imports, to import the wrapper I want to compile the projects.
The projects have some cone shaded and some are separate, but there is no duplicating anything except of couple of wrappers etc.
I think it is the best what I can do.
Following the explanation about :gen-class in The Anatomy of gen-class, I used leiningen to get the class files.
leon new pinger to create a project.
cd src and mkdir some and created a Example.clj file in it.
Added :aot [some.Example] (or :aot :all) in project.clj.
The Example.clj is as follows:
(ns some.Example
(:gen-class))
(defn -toString
[this]
"Hello, World!")
Then I executed lein compile to get the classes in target directory.
Then, I was executing this code with lein repl.
(-toString (some.Example.)) ; should return "Hello, World!"
However, I got this error message.
CompilerException java.lang.RuntimeException: Unable to resolve symbol:
-toString in this context, compiling:(/private/var/folders/nw/dmb7jh3d2hq89296z2gnntqm0000gn/T/form-
init7145760420048735997.clj:1:1)
.toString works fine.
user=> (.toString (some.Example.))
"Hello, World!"
The website explains that I should get the same results from both -toString and .toString, but I got only correct results with .toString.
What's the difference between -toString and .toString in Clojure? Why -toString raises an error in the example?
First, some terminology:
(.toString (some.Example.)) is a call to the toString method of the newly constructed some.Example instance.
(-toString (some.Example.)) is a regular Clojure function call, with -toString being the name of a Clojure Var storing a function and (some.Example.) being its sole argument.
:gen-class arranges things so that the -toString Var backs the toString method; that is, any call to the toString method of a some.Example instance results in a call to -toString. So it is indeed the case that just calling -toString directly is equivalent.
However, before you can call a Clojure function by referring to the Var in which it's stored, you need to make sure the namespace in which this Var lives has been loaded (not a problem here, given that you were able to construct an instance of some.Example) and then either refer to the Var by its fully-qualified name, or else use refer, use, require or alias to make it possible to refer to it by a shorter name:
(some.Example/-toString ...)
(use '[some.Example :only [-toString]])
(-toString ...)
(require '[some.Example :refer [-toString]])
(-toString ...)
(require '[some.Example :as se])
(se/-toString ...)
;; refer and alias are typically not used directly
If you say -toString without first using refer, use or require as shown above1, Clojure will attempt to resolve the symbol -toString to a Var in the current namespace (typically user in REPL sessions; with lein repl it may be the :main namespace from your defproject form).
1 That's speaking about the REPL. In a source file, you'd typically use :use or :require in your ns form; the syntax is the same as for use / require minus the quoting.
I want to make Clojure/Java bindings for the EFL. JNA appears to require a lot of explicit struct mapping (Bridj does the same thing). JNI has Gluegen, so I thought that might be simpler.
Going with Gluegen & deciding the Elementary module would be a good place to start, I ran:
java -jar /usr/share/java/gluegen2.jar -I. $(pkg-config elementary --cflags) /usr/include/elementary-0/Elementary.h
...and quickly found I'd need to create a ton of header stubs ie > 29
I've got three questions:
What's the fastest and easiest way to generate Java bindings for this project?
If Gluegen, is there a program for generating salient header stubs?
If JNA, is there a program for generating salient Pointer/Struct mappings?
Quick followup. It does appear that I can do some things out of the box with clojure-jna
user=> (use 'net.n01se.clojure-jna)
nil
user=> (jna-invoke Integer eina/eina_init)
1
user=> (jna-invoke String eina/eina_str_escape "They'll start going ripe on us pretty soon.")
"They\\'ll\\ start\\ going\\ ripe\\ on\\ us\\ pretty\\ soon."
user=> (vec (jna-invoke (class (into-array String [])) eina/eina_str_split "Calvin;Leoben;D'anna;Simon;Dora2;105Rl;Six;Daniel;Sharon" ";" 0))
["Calvin" "Leoben" "D'anna" "Simon" "Dora2" "105Rl" "Six" "Daniel" "Sharon"]
user=> (jna-invoke Integer eina/eina_shutdown)
0
JNAerator will generate bindings for you, for both JNA and Bridj.
I'm trying to use boilerpipe from JRuby. I've seen the guide for calling Java from JRuby, and have used it successfully with another Java package, but can't figure out why the same thing isn't working with boilerpipe.
I'm trying to basically do the equivalent of this Java from JRuby:
URL url = new URL("http://www.example.com/some-location/index.html");
String text = ArticleExtractor.INSTANCE.getText(url);
Tried this in JRuby:
require 'java'
url = java.net.URL.new("http://www.example.com/some-location/index.html")
text = Java::DeL3sBoilerpipeExtractors::ArticleExtractor.INSTANCE.getText(url)
This is based on the API Javadocs for boilerpipe. Here's the error:
jruby-1.6.0 :042 > Java::DeL3sBoilerpipeExtractors::ArticleExtractor
NameError: cannot load Java class deL3sBoilerpipeExtractors.ArticleExtractor
from org/jruby/javasupport/JavaClass.java:1195:in `for_name'
from org/jruby/javasupport/JavaUtilities.java:34:in `get_proxy_class'
from /usr/local/rvm/rubies/jruby-1.6.0/lib/ruby/site_ruby/shared/builtin/javasupport/java.rb:45:in `const_missing'
from (irb):42:in `evaluate'
from org/jruby/RubyKernel.java:1087:in `eval'
from /usr/local/rvm/rubies/jruby-1.6.0/lib/ruby/1.8/irb.rb:158:in `eval_input'
from /usr/local/rvm/rubies/jruby-1.6.0/lib/ruby/1.8/irb.rb:271:in `signal_status'
from /usr/local/rvm/rubies/jruby-1.6.0/lib/ruby/1.8/irb.rb:270:in `signal_status'
from /usr/local/rvm/rubies/jruby-1.6.0/lib/ruby/1.8/irb.rb:155:in `eval_input'
from org/jruby/RubyKernel.java:1417:in `loop'
from org/jruby/RubyKernel.java:1190:in `catch'
from /usr/local/rvm/rubies/jruby-1.6.0/lib/ruby/1.8/irb.rb:154:in `eval_input'
from /usr/local/rvm/rubies/jruby-1.6.0/lib/ruby/1.8/irb.rb:71:in `start'
from org/jruby/RubyKernel.java:1190:in `catch'
from /usr/local/rvm/rubies/jruby-1.6.0/lib/ruby/1.8/irb.rb:70:in `start'
from /usr/local/rvm/rubies/jruby-1.6.0/bin/irb:17:in `(root)'
Looks like it didn't parse the camelcase into the appropriate Java package name. What am I doing wrong? I believe I've set up my classpath alright (last 3 entries), though there may be some conflict with xerces possibly being included twice:
$ echo $CLASSPATH
:/jellly/Maui1.2:/jellly/Maui1.2/src:/jellly/Maui1.2/bin:/jellly/Maui1.2/lib/commons-io-1.4.jar:/jellly/Maui1.2/lib/commons-logging.jar:/jellly/Maui1.2/lib/icu4j_3_4.jar:/jellly/Maui1.2/lib/iri.jar:/jellly/Maui1.2/lib/jena.jar:/jellly/Maui1.2/lib/maxent-2.4.0.jar:/jellly/Maui1.2/lib/mysql-connector-java-3.1.13-bin.jar:/jellly/Maui1.2/lib/opennlp-tools-1.3.0.jar:/jellly/Maui1.2/lib/snowball.jar:/jellly/Maui1.2/lib/trove.jar:/jellly/Maui1.2/lib/weka.jar:/jellly/Maui1.2/lib/wikipediaminer1.1.jar:/jellly/Maui1.2/lib/xercesImpl.jar:/jellly/boilerpipe-1.1.0/boilerpipe-1.1.0.jar:/jellly/boilerpipe-1.1.0/lib/nekohtml-1.9.13.jar:/jellly/boilerpipe-1.1.0/lib/xerces-2.9.1.jar
I'd recommend against trying to guess the module name we put under Java::, since for unusual packages it can get mangled pretty badly. Use java_import 'your.weird.package.ArticleExtractor' or if all the package components are compatible with Ruby method naming, you can also do Java::your.weird.package.ArticleExtractor.
Also, since you might run into this... you'll want to reference the INSTANCE variable as ArticleExtractor::INSTANCE, since we map it as a Ruby constant.
Have fun!
You can also use the nice Jruby Boilerpipe Gem which wraps the Java code
Or the pure ruby implementation of Boilerpipe Ruby Boilerpipe Gem
require 'boilerpipe'
Boilerpipe::Extractors::ArticleExtractor.text("https://github.com/jruby/jruby/wiki/AboutJRuby")