I have been using processing for a while and ran into an issue when I am trying to add an external java library. I followed all the steps provided online where I have to access the lib folder(processing-3.3) and add my library inside there. Unfortunately, my method did not work. Another problem I am facing is I don't know how to import this library. This is the link to the library and this is the .jar file link. Can somebody help?
Regards
Kevin's comment is great: that is the simplest method of using a .jar that isn't wrapped as a Processing library (or setup with that structure). Simply drag and drop the .jar file into your sketch.
If you only have a single sketch to prototype with and share, this is by far the easiest option.
If you need to use the .jar in multiple sketches, and perhaps share that with others, you can use the method bellow on mimicking a Processing library structure.
That library isn't wrapped as a Processing library and depends on the Apache Commons Math library. In theory, you could use that in Processing, but it's long winded, as you'd have to:
Download commons-math3-3.6.1-bin.zip
Unzip it, and rename commons-math3-3.6.1.jar to commons_math.jar (Processing is restrictive on certain characters in library names)
Make a folder in Documents/Processing/libraries named commons_math then inside of it another folder named library (so you'll have Documents/Processing/libraries/commons_math/library)
Copy commons_math.jar in Documents/Processing/libraries/commons_math/library
Restart Processing
At this point, you should be able to do this in Processing: Sketch > Import Library... > (Contributed) commons_math and you'll see ALL the packages imported. You should be able to run the sketch, demonstrating you can use the library.
Next up is the trilateration library, which isn't build, so you'll need install/setup gradle, build it, then repeat the procedure above for the trilateration library. An alternative is to create 3 tabs in the sketch(to try and keep it tidy), one for each of trilateration library classes, copy the source code, remote the public modifier prefixing each class (as Processing sketches in the Processing IDE allow a single public class) and remove the package declaration.
Finally you should be able to use this library in Processing...phew!
It's tedious, a pain to maintain, etc., etc. ,etc.
I recommend using eclipse instead. If you want to save time creating a Processing Project, instead of manually copying the Processing core libraries, creating a main class extending PApplet, etc. you can install Proclipsing.
It's an eclipse plugin that makes it easy to create Processing Java projects.
Once you're in eclipse and can run a basic sketch, all you need to do is:
Add the Apache Commons Math jar into the projects lib/user folder
Add the library to the build path
Download/unzip the trilateration library
From the library folder's src/main/java drag the com folder on top of the eclipse project's src
Copy the example code from the library's readme:
Notice some code is in red, because the classes aren't imported. Press CMD+Shift+O(on OSX)/Ctrl+Shift+O(on Linux/Windows). This will organize imports (and do the job for you). The first suggestion works like a charm:
Right click the sketch and choose Run As > Java Application:
Woo hoo! You can run the sample code now.
It doesn't look impressive though: nothing is displayed, not even in console, but hey, it compiles :D
You can easily add a few print statements to see the results:
println(centroid);
println("standardDeviation",standardDeviation);
println("covarianceMatrix",covarianceMatrix);
At this point you can start modifying the code do what you want it to do.
Bare in mind most drawing functions in Processing take float arguments and this library works mostly with double so be sure to cast from double to float before drawing.
If you've been using Processing for a while, the eclipse route sounds doable and there's so many nice features in the IDE to speed up development.
Is there a faster way ? Could be: have a look at the M2E which makes it easy to integrate with Maven in eclipse. The trilateration library has Maven support. In theory, you can have Maven do the heavy tedious work of adding the Apache Commons Math, compile and add the trilateration library to your project. This is going further from Processing land and moving more into Java territory, but if you have the time: it's work exploring. The more Java you know, the easier it will be to get Processing to do your bidding :)
In an ideal, you would use the Processing Library Template to not only use the .jar you plan to use, but also add utility functions to interact with PApplet directly (perhaps convert between org.apache.commons.math3 Vector types to Processing PVector, etc.).
This could then be easily be shared publicly with the wider Processing community.
Related
I'm trying to make an addresslist in Java, which saves its contents in a Sqlite database.
Therefor (and for other future uses), I tried to create my own library for all kinds of database connections ("PentagonsDatabaseConnector-1.0.jar"). It currently supports Sqlite and MySql.
It references other libraries for them to provide the JDBC-drivers ("mysql-connector-java-8.0.16.jar" and "sqlite-jdbc-3.30.1.jar").
Problem: My Library works just fine if I'm accessing it from its own project folder, but as soon as I compile it and add it to the "Adressliste"-project, it isn't able to find the JDBC-drivers anymore (I can access the rest of my self-written library without problems though). Also, as shown in the screenshot, "PentagonsDatabaseConnector-1.0.jar" brings the JDBC-libraries with itself in "lib"-folder.
LINK TO THE SCREENSHOT
Do you guys have an idea whats wrong?
Thank you for your help!
Ps: Sorry for bad English, I'm German :)
Java cannot read jars-in-jars.
Dependencies come in a few flavours. In this case, PentagonsDC is a normal dependency; it must be there at runtime, and also be there at compile time.
The JDBC libraries are a bit special; they are runtime-only deps. You don't need them to be around at compile time. You want this, because JDBC libraries are, as a concept, pluggable.
Okay, so what do I do?
Use a build system to manage your dependencies is the answer 90%+ of java programmers go to, and what I recommend you do here. Particularly for someone starting out, I advise Maven. Here you'd just put in a text file the names of your dependencies and maven just takes care of it, at least at compile time.
For the runtime aspect, you have a few options. It depends on how your java app runs.
Some examples:
Manifest-based classpaths
You run your java application 'stand alone', as in, you wrote the psv main(String[]) method that starts the app and you distribute it everywhere it needs to run. In this case, the usual strategy is to have an installer (you need a JVM on the client to run your application and neither oracle nor any OS vendor supports maintaining a functioning JVM on end-user's systems anymore; it is now your job – this is unfortunately non-trivial), and given that you have that, you should deploy your jars such that they contain in the manifest (jars are zips, the manifest ends up at META-INF/MANIFEST.MF):
Main-Class: com.of.yourproj.Main
Class-Path: lib/sqlite-jdbc.jar lib/mysql-jdbc.jar lib/guava.jar
And then have a directory stucture like so:
C:\Program Files\yourapp\yourapp.jar
C:\Program Files\yourapp\lib\sqlite-jdbc.jar
C:\Program Files\yourapp\lib\mysql-jdbc.jar
Or the equivalent on any other OS. The classpath entries in the manifest are space separated and resolved relative to the dir that 'yourapp.jar' is in. Done this way, you can run yourapp.jar from anywhere and it along with all entries listed in Class-Path are now available to it.
Build tools can make this manifest for you.
Shading / Uberjars
Shading is the notion of packing everything into a single giant jar; not jars-in-jars, but unpack the contents of your dependency jars into the main app jar. This can be quite slow in the build (if you have a few hundred MB worth of deps, those need to be packed in and all class files need analysis for the shade rewrite, that's a lot of bits to process, so it always takes some time). The general idea behind shading is that deployment 'is as simple as transferring one jar file', but this is not actually practical, given that you can no longer assume that end users have a JVM installed, and even if they do, you cannot rely on it being properly up to date. I mention it here because you may hear this from others, but I wouldn't recommend it.
If you really do want to go for this, the only option is build systems: They have a plugin to do it; there is no command line tool that ships with java itself that can do this. There are also caveats about so-called 'signed jars' which cannot just be unpacked into a single uberjar.
App container
Not all java apps are standalone where you provide the main. If you're writing a web service, for example, you have no main at all; the framework does. Instead of a single entrypoint ('main' - the place where your code initially begins execution), web services have tons of entrypoints: One for every URL you want to respond to. The framework takes care of invoking them, and usually these frameworks have their own documentation and specs for how dependencies are loaded. Usually it is a matter of putting a jar in one place and its dependencies in a subdir named 'lib', or you build a so-called war file, but, really, so many web frameworks and so many options on how they do this. The good news is, usually its simple and the tutorial of said framework will cover it.
This advice applies to any 'app container' system; those are usually web frameworks, but there are non-web related frameworks that take care of launching your app.
Don't do these
Don't force your users to manually supply the -classpath option or mess with the CLASSPATH environment variable.
Don't try to write a custom classloader that loads jars-in-jars.
NB: Sqlite2 is rather complicated for java; it's not getting you many of the benefits that the 'lite' is supposed to bring you, as it is a native dependency. The simple, works everywhere solution in the java sphere is 'h2', which is written in all java, thus shipping the entire h2 engine as part of the java app is possible with zero native components.
I have a library that I'm using in an Java application - it's important for certain functionality, but it's optional. Meaning that if the JAR file is not there, the program continues on without issue. I'd like to open source my program, but I can not include this library, which is necessary to compile the source code as I have numerous import statements to use the API. I don't want to maintain two code sets. What is the best way to remove the physical jar file from open source release, but still maintain the code to support it where other people could still compile it?
the typical approach taken is to define the wrapper API (i.e. interfaces) and include those interfaces in the open sourced code, and then provide configuration options where one can specify class names of classes that implement certain interfaces.
You will import API interfaces instead of importing classes directly into your open sourced code. This way, you are open sourcing the API but not the implementation of the parts that you do not want to open source or you cannot open source.
There are many examples, but take a look at JDBC API (interfaces) and JDBC drivers (implementation classes) for starters.
I was pretty much typing the same thing as smallworld with one addition. If this API were necessary you can use a project build tool like Maven to handle the dependencies on you project. If someone checks it out from source control with the pom they can download the dependencies for themselves and you don't have to include them in a source repo.
There's probably a number of ways to fix this, here's a couple I can think of:
If you have only a couple of methods you need to invoke in the 3rd party library, you could use reflection to invoke those methods. It creates really verbose code, that is hard to read though.
If you don't have too much of the API in the 3rd party library you use, you could also create a separate JAR file, containing just a non-functional shell of the classes in the library (just types with the same names and methods with the same signatures). You can then use this JAR to distribute and compile against. At run-time you'd replace it with the real JAR if available.
The most common way is probably to just create a wrapper API in a separate module/project for the code that is dependent on the 3rd party library, and possibly distribute a pre-built JAR. This might go against your wish to not maintain two code sets, but may prove to be the best and less painful solution in the long run.
I was just wondering, I am designing a library to use with my Android projects. Now I am starting to include things like the apache FTP jar to support some debug file uploads.
I know that not all projects will use all parts of the library (e.g. some project will not have an FTP upload at all, but wants to use the UI tools from the library).
Now I got three questions:
Does Proguard remove unsused sources (own code), like e.g. my UI tool classes, if they are never references from the main project - meaning not used in the application.
Does Proguard remove external libraries (e.g. apache ftp jar) if never used. If not, I may include the source, if option 1 applies.
How about resource files (not really Proguards job, more IntelliJ or Eclipse) - Example: I write a google map extension using default markers, stored in the library project. If I do not need the maps anyway, do the files get included in each android project - and is there an easy way to prevent that.
Some more backround: I try to keep all my library stuff in one project as long as possible. I don't know a good point to split the library yet, so I don't want to overkill to create seperate libs for everything (did that in the past, and most of the time it was way to much modularization)...
Thanks for any insights,
Chris
Does Proguard remove unsused sources
It tries to, when configured properly.
Does Proguard remove external libraries (e.g. apache ftp jar) if never used.
It tries to, when configured properly.
How about resource files (not really Proguards job, more IntelliJ or Eclipse) - Example: I write a google map extension using default markers, stored in the library project. If I do not need the maps anyway, do the files get included in each android project - and is there an easy way to prevent that.
No.
I am developing a java web application and that includes an applet. That applet is
dependent on two jar files:
JFreeChart (for plotting graphs at the client side) - 1.7 mb(size of
jar file)
MySqlJdbcConnector (for storing data, captured at the client side, to
a remote database) - .7 mb (size of
jar file)
Now, the problem is the size of above
two jar files. The total size of my
applet jar (myApplet.jar) is 2.5
mb out of which 2.4 mb is
because of the above two jar files.
I am not using all the classes in
those jar files. Specifically, for
jfreechart, I am using a very small number of classes from that
library.
Questions
Q1. For creating myApplet.jar file, what I have done is I have unzipped both of the jar files (jfreechart and mySQLJdbcConnector) and then packed the unzipped version of the jar files with the source code of my applet code to create one single jar file (i.e myApplet.jar). Is it the correct way of packing third party jar files with your applet code? Is there any way by which I can optimize this?
Q2. I tried to find the dependencies of the classes of jfreechart library which I am using in my application so as to pack only those dependencies in myApplet.jar. For that purpose, I used DependencyAnalyzer to find the dependencies of all the classes. But later I found it difficult to do so manually because every class (class of jfreechart that I am using in my application) has lot of dependencies and I am using some 15 classes of jfreechart so doing this for every class will be very difficult. So any suggestion on this?
Q3. Is this situation very common that developers encounter or I am missing something because of which I have to do this?
I'd suggest trying out ProGuard. You can exclude parts of jar files you're not using.
Yes you can save space by creating a JAR containing only the classes that your applet requires. (I've seen this called an uber-JAR.)
There are various tools for doing this; e.g. ProGuard, Zelix ClassMaster, a Maven plugin whose name I forget and so on.
There are however a couple of issues, at least in the general case:
If your code uses dynamic loading (e.g. by calling Class.forName(className)), these tools generally cannot detect the dependency. So to avoid dynamically loaded classes being left out of the final JAR, you need to tell the tool the names of all of all classes that your application might explicitly load that way.
You need to take a look at the license of the third party library. IIRC, some licenses require you to include the library in your distributed artifacts in a way that allows people to substitute a different version of the library. One could argue that an uber-JAR makes this hard to do, and therefore could be problematic.
JFreeChart is LGPL, and LGPL is a license that has the requirement above. However MySQL is GPL, which trumps LGPL, and this means that your applet must be GPL'ed ... if you distribute it.
Finally, if you want to minimize the size of your applet JAR, you should NOT include your source code in the JAR. Source code should be in a separate JAR (or ZIP, TAR or whatever) file.
A1:
You can create an ant script or use Eclipse or any other IDE to automatically package your applet. But your way is correct, too
A2:
I wouldn't do these things manually. Finding transitive dependencies is very complex. Maybe darioo's answer is a better way to do this.
A3:
This is very common indeed. A couple of hints:
You can always re-build those third party libraries without debug information. That should slightly decrease the size of those libraries.
On the other hand, maybe you shouldn't have a direct connection from your applet to a database. You could create an RMI interface (or something similar) to transfer your SQL and result data to an application server, which actually executes your SQL. This is an important security aspect for your applet, if you don't run this in a safe intranet.
I am very new to java and android development and to learn I am trying to start with an application to gather statistics and information like munin does. I am trying to be able to load "plugins" in my application. These plugins are already in the application but I don't want to have to invoke them all separately, but be able to iterate over them. I was trying to use serviceloader but could never get the META-INF/services into my apk. So I am wondering if it is possible to use serviceloader on android
Thanks
EDIT: I am asking about java.util.ServiceLoader, I think it should, but I can't figure out how to get my services folder into META-INF on the apk
There is an open bug report against this issue. See https://code.google.com/p/android/issues/detail?id=59658
The META-INF folder is deliberately excluded from the APK by ApkBuilder; the only comment in ApkBuilder.java is "we need to exclude some other folder (like /META-INF)" but there is no other explanation.
Even after adding META-INF with ant, you will still get in trouble if you want to use Proguard, which refuses to replace the content of META-INF/services/* files or rename them (that's another story, the author wants to keep Proguard agnostic).
However, people using maven may want to check https://github.com/pa314159/maven-android-plugin (the branch named "modified"), that tries to solve both issues. It is a fork from the original "android-maven-plugin" I modified one month ago for my own Android projects.
It also provides a patch for Proguard-4.7
Hope this helps, any feedback is welcome.
I've figured out a solution that may work for some situations. Instead of ServiceLoader, I'm using the org.openide.util.Lookup class / library that comes with NetBeans - it is a superset of ServiceLoader. It does not require NetBeans itself and seems to work ok with Eclipse. It is necessary to replace whatever ServiceLoader functionality you are using in your application with Lookup equivalents, and add the org-openide-util-lookup library. Then, you can just do something like this:
Lookup lookup = new ProxyLookup(Lookup.getDefault(),
Lookups.metaInfServices(myClass.getClassLoader(), "services/"));
And move your ServiceLoader files from META-INF/services/ to services/.
Note that, because of the ProxyLookup, this will continue to work on standard Java environments unchanged (i.e., in those cases it will continue to look in META-INF/services).
Here is a link to the documentation for the library: http://bits.netbeans.org/dev/javadoc/org-openide-util-lookup/org/openide/util/lookup/Lookups.html
UPDATE
After working with this for a couple of days, it seems to function well - I move between environments (standard Java and Android) and it works properly in each location. The primary downside is having to manually copy the files to the /services directory.
It is possible. You may want to check http://developer.android.com/reference/java/util/ServiceLoader.html
ServiceLoader is stuff from the Java language that is not really relevant on Android. I recommend not using it. If you just want to find a list of classes within your .apk to load, there are all kinds of ways to do this -- put in XMl file in res/xml that lists them, use reflection, annotations, etc.