Repackaging the .jar file - java

I need to add some jars from JRE7 library to my Android project. But for example rt.jar is in conflict with android.jar from Adroid 2.2 SDK, so I get this error:
Ill-advised or mistaken usage of a core class (java.* or javax.*)
when not building a core library.
This is often due to inadvertently including a core library file
in your application's project, when using an IDE (such as
Eclipse). If you are sure you're not intentionally defining a
core class, then this is the most likely explanation of what's
going on.
However, you might actually be trying to define a class in a core
namespace, the source of which you may have taken, for example,
from a non-Android virtual machine project. This will most
assuredly not work. At a minimum, it jeopardizes the
compatibility of your app with future versions of the platform.
It is also often of questionable legality.
If you really intend to build a core library -- which is only
appropriate as part of creating a full virtual machine
distribution, as opposed to compiling an application -- then use
the "--core-library" option to suppress this error message.
If you go ahead and use "--core-library" but are in fact
building an application, then be forewarned that your application
will still fail to build or run, at some point. Please be
prepared for angry customers who find, for example, that your
application ceases to function once they upgrade their operating
system. You will be to blame for this problem.
If you are legitimately using some code that happens to be in a
core package, then the easiest safe alternative you have is to
repackage that code. That is, move the classes in question into
your own package namespace. This means that they will never be in
conflict with core system classes. JarJar is a tool that may help
you in this endeavor. If you find that you cannot do this, then
that is an indication that the path you are on will ultimately
lead to pain, suffering, grief, and lamentation.
I know there have been several threads about it and things like JarJar, OneJar or FatJar might be good for me. But I don't know how to make any of them work and documentation doesn't really make it clear (for me). I guess they use Ant commands, but I have always used Eclipse built-in builder and now I have no idea how to use neither Ant nor any of mentioned above.
So my question is: how can I repack this rt.jar so I could compile it in my Android project?
Thank you!
EDIT:
Ok, so what I want to achieve is to create a .jar, which can be used during developing Android application (simplifies some functionalities, doesn't really matter). But I would also like to be able to add the very same .jar to standard Java project in order to use some functions there as well. It would look like this:
Whoever writes an application adds this .jar to his Java project -> it enables him to generate certain files (internet is needed to do it) -> these generated files are then added to Android project -> later on, when somebody uses this Android app, these files provide certain functionalities without using internet (off-line).

It would be ill-advised to do this in any project at all, even if it were possible. You would be opening yourself to a wealth of class incompatibility and loading problems. But in any case it doesn't even matter because the core Java libraries are loaded way before your archives are even touched, making any such attempt at overriding them moot.
Not to even talk about the fact that Android is using its own JVM implementation which is not fully compatible with JDK 6 (forget JDK 7). Also note that it may be a copyright violation to package the core Java libraries with your code and could change your licensing options (IANAL).
You need to find another way to resolve whatever issue you are having (which you failed to mention in your question).

There are many JARs that work nicely on both Android and on classic Java. None involve having Android developers pirate rt.jar. Stick to java.* and javax.* classes that exist in both the Android SDK and in whatever level of Java you are supporting, and your JAR will work fine in both environments.

You should ideally refrain from using such .jar files, but if you must, you can add them to build path. But this, at times results in a conflict, like the one that you are facing right now. What you need to do to resolve this kind of a conflict, is:
add the jar in the build path.
Check "referenced libraries". The jar file should appear under the same.
once it features under referenced libraries, check the "android dependencies" virtual directory. If you get to see that you have an instance of the same jar file there as well, you should delete the "android dependencies" folder altogether. (Trust me, this does not affect your project in any way).
having done that, you should be able to compile your code without any further conflicts.
Happy coding.. :)

Related

JavaFX and IntelliJ no errors althought the documentation says I should have some

I'm currently following this tutorial: https://openjfx.io/openjfx-docs/ (JavaFX and IntelliJ IDEA). I use Intellij 2021.3.2.
I have created a project (1. Create a JavaFX project), which worked out great and didn't need to 2. Set JDK 16 because it was already set to 17 (which I guess is fine).
But here begin the weird stuff (and I'm very new to programming so I'm sorry if it sounds silly). "You can also set the language level to 11 or greater." I don't have this option. Because it's "can" I felt like it wasn't a big deal but if someone can explain what this is all about? Just out of curiosity, because I'm at the very beginning of the tutorial and I kinda only understand half of it.
Then 3. Create a library, and I don't have what they have, and my stuff is red:
So when they said "add the JavaFX 17 SDK as a library to the project" I didn't know what to do. I also didn't know what to do to fix the red stuff.
And finally, they say "Warning: If you run now the project it will compile but you will get this error: ..." but if I click on this button
everything works! which you know i'm not complaining about but I would like to understand a bit more what is happening.
And then they suggest I should 4. Add VM options to fix the problem that I don't have. So I figured maybe my computer set the VM options correctly without me knowing it but there is currently no VM option (and it works). Should I add them nonetheless?
Thank you for your help, I'm very lost and feel like I don't really understand anything.
The current documentation in the openjfx tutorial for getting started with JavaFX using Idea is incorrect, at least for recent Idea releases (2021.3 +).
The tutorial is written as though a new Java project was created, rather than a new JavaFX project. Once a new JavaFX project has been created, most of the rest of the steps in the tutorial are either redundant or wrong.
Step 1, “Create a JavaFX project", does a lot more than just “Create a Java project”, which is why everything else is different from the tutorial.
A better tutorial for getting started with JavaFX with Idea, is the official Idea documentation:
Create a new JavaFX project.
Differences between creating a new Java project and creating a new JavaFX project
The new JavaFX project:
Provides a build script for Maven (pom.xml) or Gradle (build.gradle).
Adds the appropriate dependencies for JavaFX base, graphics, controls and fxml.
Provides an example application and controller code that you can run immediately.
The example project is modular and provides a module-info.java
Because the program is modular and dependencies are downloaded via maven and recognized by the IDE, you don’t need to manually configure VM runtime options for the module path and adding modules.
Idea will recognize the Maven or Gradle projects and automatically synchronize the initial transitive dependent libraries with the Idea project.
There are options in the Idea Maven tool window which will allow you to synchronize further changes to dependent libraries or javadoc and source code in libraries.
Selects a JDK and attaches it to the project, automatically downloading the selected JDK version if not already present.
Sets an appropriate language level for the project.
When you just use the create new Java Project option, it doesn’t do any of those things, so you need to do things manually instead, which is what the rest of that tutorial is about:
Manually download the JDK and configure it in the SDK.
Manually download the JavaFX SDK and add the libraries from it to your project.
Manually configure VM modular arguments.
Manually maintain any other dependencies.
Manually associate javadoc and source code.
Manually write the code for a basic application.
Manually set the project language level.
Doing all this stuff manually is more work and more error prone. The manual work usually leads to a worse outcome and a project that is more difficult to maintain for many people getting started with JavaFX, so I do not recommend it.
Versions
In terms of the versions to use, I recommend using the most recent stable (non-beta) releases of both JDK and JavaFX, regardless of what versions may be referenced in any tutorials you may be using.
You can set JavaFX versions in the Maven file generated by the new JavaFX project wizard, then press the button in the Maven Tool window to synchronize the Maven project with the Idea project.
Language level settings
These are important later on, but pretty irrelevant when just getting started.
The language level settings:
Tell the compiler what version of the java byte code to compile the application to.
Tell the IDE what language syntax rules to enforce and provide help with.
If you use Java 17 only features, the app won’t run on a Java 11 VM.
You can define the settings in Idea manually:
language setting level.
But it is better to set them in the compiler section of the maven project and synchronize the project with Idea, which will also configure the settings in the IDE.
IMO, set it to the most recent stable version and have a requirement that your application be run with that Java version as a minimum (you can enforce that by using jlink or jpackage to bundle the JRE version you choose with your packaged app).

Which of these 3 locations should Java3D be kept in?

Right now I'm trying to get Java3D to work with JDK 1.8.0 in Eclipse on OS X. I've tried following this tutorial (among many others) and am finding varying levels of no success. I believe part of the problem is that there are currently 3 separate locations with the Java3D .jars are ending up on the build path:
/Library/Java/Extensions/ as a part of the JRE system library
/System/Library/Java/Extensions/ as a part of the JRE system library
My personal libraries folder as external included .jar files
Earlier in project development, I hadn't updated the files in the Library folders (they were whatever came with the Mac), and in that case there were no Eclipse errors, but the project could not be run (UnsatisfiedLinkError: no j3dcore-ogl in java.library.path)
Now that I've updated both of the JRE system library .jar files, the code has errors: Access restriction: The type '...' is not API (restriction on required library '/Library/Java/Extensions/j3dcore.jar')
What's the proper way to clean up all these locations so that the project only references one set of these .jars, and where should these .jar's be?
There is only one way to clean up: uninstall all those obsolete versions of Java3D provided by Apple ("whatever came with the Mac") and follow my instructions.
The extension mechanism has been removed from Java 1.9, relying on it is a very bad idea. Only use a carefully chosen "personal libraries folder" whose scope affects only your application and not the rest of the operating system.
If you need some help on Java3D, rather use its official forum.

How can I convert an eclipse-dependent application into an eclipse-independent application?

I developed an application in eclipse that uses many of the classes of the eclipse framework and requires eclipse to run. But now I'm being required to decouple it from eclipse and make it a standalone application. How can I do this?
You might have luck using File / Export... / Java / Runnable Jar File. This will create a standalone .jar file that should be possible to run without Eclipse. You may however need to experiment with the various settings to get it to behave exactly how you want depending on what libraries you are using.
In general however, I'd suggest using a proper build/dependency management tool such as Maven. This will take a bit of time to learn at first, but my experience is that it will make you more productive in the long run....
Start by commenting out the imports for the offending libraries. This will turn red any references to those libraries in your code. Then substitute a different library or refactor your code.
What do you mean by "decouple" it from eclipse? Do you mean you can no longer rely on any of the eclipse libraries, or that you simply don't want it running as a module in the IDE?
If it's the former, you have a lot of rewriting to do.
If it's the latter, then you'll want to basically bundle your module with an "empty" eclipse framework application. This doesn't "unbundle" eclipse, eclipse is still there, but now you don't have any of the IDE modules etc, and instead you have a stand alone ECLIPSE BASED application.
Create a standalone jar file from the Eclipse project as mentioned by Mikera, or you need to re-factor the code such that it doesn't depend on Eclipse libraries.
There is no point in creating a Java application which depends on certain IDEs or platforms. Java code should be independent (which is why it has the power to run on any platform which has JVM installed in it.
Try removing the dependency from your project to the Eclipse libraries. See if you can simulate the same thing using Standard Java libraries. If not, try to create a JAR for your project from Eclipse. If nothing works out, try looking for some 3rd party APIs.

Java Classloader - how to reference different versions of a jar

This is a common problem. I'm using 2 libraries A.jar and B.jar and these depend on different versions of the same jar.
Let's say that at runtime I need THIS.x.x.x.jar
MY.jar
-> A.jar -> THIS.1.0.0.jar
-> B.jar -> C.jar -> THIS.5.0.0.jar
I can compile the specific jar (A.jar/B.jar) against its dependency but at runtime I've to load only 1 version. Which one?
Loading only 1 dependency (the latest version) means that my code will probably throw runtime exceptions if the libraries are not Backward Compatible (are there Backward Compatible libraries out there?).
Anyway I know that something like OSGi can fix this issue.
I'm wondering what's the old way to fix this kind of problems...
Thanks a lot
"Old way" you mentioned (and the one OSGI certainly uses under the hood) is to install your own ClassLoader for both branches of your dependencies. That's how, for instance, application servers are able to run both older and newer versions of the same application inside the same JVM.
Read about classloader hierarchy.
In your setup, the tricky part is the joint point, where classes from both branches meet. Neither branches can use classes loaded into another one. The way to make it work is to make sure only classes loaded by boot classloader (JRE classes) or classloader of MY.jar are passed down to both branches.
OSGi can fix this problem. An OSGi bundle is nothing more than a jar with additional metadata detailing versions. A bundle has a version number, and will detail version numbers (or ranges) of dependent jars.
Take a look at this introductory Javaworld article for more information.
To solve this without OSGi means having to ensure manually that you compile and run with compatible jars. As you've discovered that's not necessarily a trivial task. Since jars don't necessarily identify their versions, the only sure way to do this to record/compare checksums or signatures.
Many libraries are backward compatible. But not all..
The old way is to try to depend from only one version.
It is probably safer to compile both with the same version (latest).
At least you get compile-time errors, instead of runtime errors.
If needed, you can modify a little bit your library that works with the old dependency...
This would require access to the source...
Please note that compile-time compatibility will not guarantee correct runtime behavior either. It is one step, then you can:
read the WhatsNew file for the new version of the jar
look on the Internet for users reporting compatibility problems
write JUnits
compare the codes in both jars
As mentioned by KLE, the default approach is to depend on the newer version. There is no guarantee, but most of the time this works. Probably the best way (while being a bloated one) is using OSGI to get over it.
To refer a basic "oldway" implementation checkout https://github.com/atulsm/ElasticsearchClassLoader
This provides an approach to handle non-backward compatible versions of elasticsearch client usage.

How well do Eclipse and Netbeans coexist?

I would like to have both Eclipse and Netbeans (with JUnit) installed on one system, so I can be somewhat familiar with both.
Besides GUI development (see "Using both Eclipse and Netbeans"), are there any other issues with using both IDEs on the same system, or even the same project?
We regularly use both Netbeans and Eclipse. We switch back and forth, between Vista, WinXP, and multiple versions of Fedora of the 32- and 64-bit variety, with no problems. Keeping the project files in version control makes keeping them in sync much easier. We even keep the launch files in the project directory as well. I posted a answer to another multiple IDEs question that describes what our project directory looks like.
Basically, I agree with Bill the Lizard about there being no issues, but disagree about the seamless nature and keeping the project files separate. The only thing we have to do is make sure that we update the build classpath in each project if a new library is added because Netbeans and Eclipse use different files to describe the classpath.
Using the IDE version control system integrations helps to encourage keeping the projects up to date for everyone else.
One thing that makes developing single project in NetBeans and Eclipse is using maven to keep dependencies together. Maven will generate IDE specific files that contain all classpath information, buildpaths etc.
Maven has pretty steep learning curve, but it is worth learning.
There are no issues at all with having them on the same system. However, each have their own project specific files, so using them on the same project isn't seamless. This is made a lot easier if you're using source control and keep your (non-source code) project files separate.
Maven is a very good way to keep both IDEs in sync (as suggested). In my experience though, you have to create an Ant build for any given project for the sake of developers not using IDEs. Since NetBeans's build system is based on Ant, it's pretty trivial to just base the entire NetBeans project off of that base build system. A little bit of tweaking in the project.xml ensures that the editor classpath is kept in sync with the Ant build classpath.
Netbeans 6.5 has an improved Eclipse project import which is supposed to sync changes from Netbeans back to Eclipse: http://wiki.netbeans.org/NewAndNoteWorthyNB65#section-NewAndNoteWorthyNB65-EclipseProjectImportAndSynchronization

Categories

Resources