Has anyone successfully created a NetBeans project that combines Clojure and Java source?
I have projects where the driver program (startup, gui, user prefs, etc.) are in Java, but the logic is in Clojure. At the moment, I compile the Clojure code to a jar in one project and import it as a library in a separate Java project. It would be convenient if all the source could be combined in one single NetBeans project.
Has anyone come up with a method to do this?
One possible solution is to modify your NetBeans Java project's Ant script (build.xml in your root directory) to have it .
By default, NetBeans creates several placeholder Ant targets in the root project directory's build.xml for you to override to automate tasks beyond the standard build process (such as compiling other languages to use their libraries in your current project). By overriding one of the placeholder targets in that build script such as "-pre-compile" you could write a simple target to call the Clojure compilation process using the Ant "exec" task and place all the resulting class files (or JAR) in the appropriate build directory.
If you do this frequently, you could define an Ant extension (via a macro or Ant plugin) so you don't have to modify the build.xml each time.
I use the RT method. I put my Clojure code into a script file that I include and process at startup:
try {
RT.loadResourceScript("com/mydomain/app/clojure_scripts.clj"); // Initialize Clojure script processor with our script
} catch (Exception e) {
Util.logException(e, "Unable to run Clojure initialization script.");
}
Then, since my main logic is in Java and I'm only calling out to Clojure for calculations, I use some glue code to map the calls for me:
/*
* Class to wrap Clojure scripts with Java friendly methods.
*/
public class Clojure {
private static final String ns="com.mydomain.app";
public static double calculate(final double size, final double otherVar) {
Var report=RT.var(ns, "calculate");
return (Double) report.invoke(size, otherVar);
}
};
Related
I have a Gradle build script which has to call a Scala (or Java) method in a Task.
currently, i have src/.../utils/lib.java
this file has a simple class with a static method that I would like to call in the build.gradle script.
but I have no idea how to import this file and use this method.
This really depends on how your gradle script is set up and what you are trying to accomplish. Without seeing it, it is hard to give a concrete all encompassing response. Here are the two most common methods I know of that would allow you to execute code in a gradle script.
1) To directly answer your response, to execute a static java method, it needs to be compiled first. If the rest of your build requires this to be executed, then you would need to structure this as a multi-project build.
https://docs.gradle.org/current/userguide/multi_project_builds.html
Assuming you have
apply plugin: 'java'
You would then be able to create a jar with the class containing your static method, and create a task that you can execute of type Exec or JavaExec that would execute this jar.
2) The easier and less complex approach:
Since gradle allows you to directly execute groovy code, if possible, I would try to move the logic from the static method into the gradle file. You can reference Objects and methods on the org.gradle.api to customize a lot of build actions.
https://docs.gradle.org/current/javadoc/
Here is an example from my build.gradle use to copy resources files after a compile step into the build directory before it is packaged into a jar.
compileJava {
doLast {
def f = file("src/main/java/resources/db/migration")
println "Copying SQL from {$f} to {$buildDir/db/migration}"
copy {
from file(f)
into file("$buildDir/db/migration")
include('*.sql')
}
}
}
This may not be the easy solution that you were looking for but I hope it gives you some good guidance.
I have an existing web application, A, which is a Maven project in Eclipse. It is run on a Tomcat 8 localhost server. Now I have a Java application, B, that was a separate project on its own. I have imported B into my workspace with A as another project. I am trying to run a main class (called App.java) which exists in B from a class within A. The class within A is below:
public void runOrgReportUtility() throws IOException {
int k = runProcess("javac /Users/ag/utilities/org-report-utility/src/main/java/com/vs/orgreport/App.java", null);
if (k==0) {
log.info("Compiled. Now trying to run class.");
String commandStr = "java -cp /Users/ag/utilities/org-report-utility/src/main/java/com/vs/orgreport/ App";
log.info("Command String: ");
log.info(commandStr);
runProcess(commandStr);
}
public int runProcess(String command, String[]) throws Exception {
Process pro = Runtime.getRuntime().exec(command);
pro.waitFor();
return pro.exitValue();
}
When I tried running A, the console gave me a bunch of error: cannot find symbol, for various classes within B. This made me realize that only the App.java was being compiled and run, and not the other dependent classes in B.
How can my second java application be compiled and run when I start up my original web application?
Things I have tried:
Set (original) project references to include secondary Java app
Add Java app project to Java build path (in Projects tab) of original project
Added Java app to Deployment Assembly of original project
Do not compile the application when you want to call it. This is bad:
Compiling with javac is hard due to all the dependencies. As you found out, it is not a simple matter of invoking javac on a single java file.
Why wait until you try to run it to find out that you have an error that keeps it from compiling?
Why incur the overhead of compiling it every time you run it?
You normally would use maven to compile B and probably use the maven-shade-plugin to create a B.jar that contains B and all dependencies (aka a "fat" jar). Then when A invokes B, you can use the fat jar as the classpath when you invoke the app that it contains.
Other things you might consider:
You could probably also include the fat jar in your web application so that you are not dependent on having an external jar that must be in place in order for your web application to be fully functional.
Rather than execute the other application in a separate process, run it in the same JVM by just calling App.main() directly. You might want it to run in a separate thread, which is easy to do.
If you really want a separate OS process, use ProcessBuilder rather than Runtime.exec. In many cases, it is an easier API to use and get right.
I have some code in an Android project that parses HTML using Jsoup. It doesn't use anything Android specific, they're just static methods that take an InputStream, and return my model classes. The app uses Gradle to build itself in Android Studio.
Is there any way I can create a standard Java main method to do something like load HTML from a local file, run it through my parser, and output a JSON file (using Gson on my model class)? I'm thinking maybe I can add a new sourceSet to Gradle like a jvmCompatible set of classes? I would greatly prefer not to copy my code to a separate project.
EDIT:
I guess I didn't make this clear, but I would like the be able to run this locally on my dev machine from the command line, rather than on an Android device or emulator.
You don't necessarily need to do anything in the build file to set this up; the build file generates Java .class files, and you can feed them to Java directly from the command line. You can add a main method to any class:
package com.example.foo;
class MyClass {
...
public static void main(String [] args) {
...
}
}
The main method will be happily ignored util you invoke it via the Java command line. You can do this by setting your classpath to the intermediate build directory and telling the Java command line which class to start:
java -classpath app/build/intermediates/classes/debug/ com.example.foo.MyClass
where you pass in the path to the build/intermediates/classes/debug directory in your app module's build output, and the fully-qualified name of the class.
Note that if you're running a release build that uses ProGuard, this main method could get stripped out if it's not otherwise referenced in the code.
Make sure you don't access any Android classes or you'll get a runtime error.
As an aside, you might find it worthwhile to separate out your Java-only code into a Java-only module in the build. Among other things, it would let you use JUnit to write nice test cases for the classes within; if you're asking this question because you want to do some testing of your parser, you might find it convenient to do so within the auspices of a unit test.
I have a Scala project and I would like to export it as a jar.
*1. At first I tried creating a Java class for the project as an entry point
public class JMain {
public static void main(String[] args) {
System.out.println("Java main calling Scala main");
SMain.main(new String[] {""}); //SMain.main is the actual *main*
and this worked fine and dandy when launched from Eclipse, but when I export it as jar it'll give me 18 exceptions or so. I do now know how to replicate then "environment" in which Eclipse manages to launch this and I'm prety sure it relies on the fact that Scala is on my system already - I need a self contained jar with everything packed in there.
*2. My second try consisted of trying what lach suggested here How to deploy a Scala project from Eclipse?
namely:
public class JMain {
public static void main(String[] args) {
System.out.println("Java Main");
List<String> argList = new ArrayList<String>();
argList.add("fully.qualified.ClassName"); //???
for (String s : args) argList.add(s);
scala.tools.nsc.MainGenericRunner.main(argList.toArray(new String[0]));
This time it won't even run from Eclipse, although it gives only 6 or so exceptions starting with the famous NoClassDefFoundError. I have a feeling I'm not getting fully.qualified.ClassName right. *3. If the main Scala class is called "Dis.scala" and is located in package "pack" shouldn't this fully.qualified.ClassName be "pack.Dis"?
I'm using Jre 1.6 and Scala 2.9.2
EDIT: I have included all external imported jars, even scala-library.jar - everything is nice and packed in the jar
P.S. I am not familiar with Ant or Maven or Sbt. I just want my Scala project jared - if possible without getting into hairy things.
Here is what worked for me:
1. Create scala project
2. Create Wrapper java project
3. Add the scala-library.jar to you java project build path.
So you only need the 3rd step in addition since the rest looks similar to what I did. Then you can happily use: java - jar file.jar
EDIT:
How to create a JAR File which contains Scala/Code which can be consumed by another Java Project, using Scala - Eclipse IDE.
Create a new Scala Project and define an object with a main method as entry point.
Now create a new Java Project and add your Scala Project to the new ones buildpath. Additionally add the scala-library.jar to the Java project.
Now create a Wrapper class in the java project which calls your entry point class from the scala lib. Run the wrapper class to create a eclipse run configuration and test if you can call the scala project.
Use the Export->Java->Runnable JAR file, Wizard now on the wrapper project.The eclipse run configuration will be used as entrypoint into the JAR. Depending on your needs you may want to :
extract required libraries into generated JAR
or
Package required libraries into generated JAR
Finally you get a complete packaged JAR which you can use like this:
java - jar wrapped.jar
For me, it was relatively straightforward.
Develop and test the project using the scala IDE (or eclipse for java).
once ready, generate the jar for the project using file -> export method.
for submitting the spark (i was writing something for spark), i just had to mention --class option for specifying the main class for the jar.
hope to help.
At the build(compile) time of my project I need to do code-generation for a java class. The generated java class is a java bean class with a set of getters and setters. At the build time I am getting the name of the class and names of variables. So what I need to do is dynamically generate the java bean from the information which I have.
eg. At the compile time I am getting following data.
class-name=Test
variable-name=aaa
So the generate class should look like following.
public class Test {
public String aaa;
public void setVar(String str) {
this.aaa = str;
}
public String getVar(){
return this.aaa;
}
}
When I searched for a tool that I can use, I found Arch4j [1] interesting but the problem with that is it is not compatible with Apache 2.0 license. I am looking for a project/tool that is compatible with Apache 2.0 license.
I would appreciate if someone can give me some insight on how I can do this.
[1] - http://arch4j.sourceforge.net/components/generator/index.html
Why not just generate the .java file during your build, using a custom ant task or Maven plugin? This seems like a rather easy task which doesn't need any complex library. You could even use a template file with placeholders for the class name and the field name, and generate the real .java file using a replace task.
JET from Eclipse can be used:
http://eclipse.org/articles/Article-JET/jet_tutorial1.html
It can be called by ant: http://help.eclipse.org/helios/index.jsp?topic=/org.eclipse.jet.doc/references/ant/antTasks.xhtml
And I think from maven: http://mvnrepository.com/artifact/org.eclipse/jet/0.8.0-v20070605
Take a look at javax.tools package. You can create and load a dynamically generated class only with that package.
Just bear in mind you need the JDK available and that's not re-distributable so your customer would need to downloaded it separately ( just like you do in any IDE today )
http://download.oracle.com/javase/6/docs/api/javax/tools/package-summary.html
For instance, you can invoke the java compiler programatically with:
http://download.oracle.com/javase/6/docs/api/javax/tools/JavaCompiler.html
And you can load it with URLClassLoader
Odd suggestion, but it seems like you want to generate beans. Why not use something like apache common's DynaBean? They allow you to create beans at run time. Here is an example of using DynaBean.
Of course this is at run time and not compile time. For compile time, I would recommend using an ant task to compile your source and add a dependency for compile on generation of your classes. You can handle the classes generation by writing a small java application that uses velocity as the java class template's engine.
So your ant task on compile first calls a small java program that generates the java class files using velocity template (delete the old files in ant if needed). Then compile as normal.