Java library search order - java

Background / example (but question is probably broader than this):
I'm trying to write a Java application that accesses a Google AppEngine server. To set up the project for this, I followed the steps outlined in the accepted answer here:
Developing a Java Application that uses an AppEngine database
I am now running into a problem where I'm trying to execute an HttpURLConnection-request in the Java client application (i.e. not in the AppEngine server code), but Google's AppEngine library seems to have replaced the Java version of this connection with its own urlFetch()-implementation. This leads to me getting the following error: "The API package 'urlfetch' or call 'Fetch()' was not found.".
Actual question:
What determines the order in which Java looks through libraries to find needed class-implementations? Is there a way to modify this order (specifically in Eclipse), so that the actual JRE-functions take precedence over a third-party-library that is also needed. Or is there maybe something special going on with the implementation of Url in the example given above, that cannot be resolved by specifying a library order?
Update:
Turns out the problem I was seeing had nothing to do with the order in which classes were loaded. The AppEngine server code explicitly calls setContentHandlerFactory(...) to register its own handler during execution rather than at library load time (see here for a fix to this specific issue). So, while my "actual question" might still stand, I haven't actually yet come across a scenario where it matters...

You might have to define a custom ClassLoader.
Also, take a look at this answer.

Inside Eclipse, you can adjust the classpath order. Right click your project, choose Properties, Java Build Path, then click the "Order and Export" tab. However, of course, this won't affect your program when running outside Eclipse.

Related

Where to keep and how to handle the version of a Java application?

I am working on a Java application and want to show the version number as part of an "About" or "Help" dialog.
UPDATE: As a clarification: I do not want to display the Java version but the version of the application.
At the moment I keep the current version information in the build.gradle and ideally, I do not need to keep track of the version in different places for runtime and while building.
I found some very old articles which suggested to get the current version from the JAR`s manifest but I am not sure if this is still the way to go.
My natural approach would be to have an application.properties file in the classpath which contains entries like application.name, and application.version. If I am not wrong those properties can be accessed by Gradle while building the distribution and as well by the application during runtime.
Are there any other ways to do such a thing I am not aware of?
System.getProperty("java.version") should do it – provided you are looking for the Java version.
If you are looking for the application's version instead, you can propagate that to the application's /META-INF/MANIFEST.MF and read it from there.

Derby, Java: Trouble with "CREATE_TYPE" statement

I've been messing around with Apache Derby inside Eclipse. I've booted up a Network Server, and I've been working with servlets. In my Eclipse project, I have a class called "User", inside the package "base.pack". I have an SQL script open, and I've been trying to convert User, which implements Serializable, into a custom type. When I run the following lines, everything works fine:
CREATE TYPE CARTEBLANCHE.bee
EXTERNAL NAME 'base.pack.User'
LANGUAGE JAVA
This follows the general format they identify here: http://db.apache.org/derby/docs/10.7/ref/rrefsqljcreatetype.html#rrefsqljcreatetype
Now, when I try to create a table using this new type, I get an error. I run the following line:
CREATE TABLE CARTEBLANCHE.TestTabel (ID INTEGER NOT NULL, NAME CARTEBLANCHE.bee, PRIMARY KEY(ID));
And I receive the following error:
The class 'base.pack.User' for column 'NAME' does not exist or is inaccessible. This can happen if the class is not public.
Now, the class is in fact public, and as I noted before, it does implement Serializable. I don't think I'm stating the package name incorrectly, but I could be wrong. I'm wondering, is this an issue with my classpath? If so, how would you suggest I fix this? I admit that I do not know much about the classpath.
Thank you.
(For reference, I have configured my project build path to include derby.jar, derbyclient.jar, derbytools.jar, and derbynet.jar, and I have put these files into my project's lib folder as well).
As politely as I can, may I suggest that if you are uncomfortable with Java's CLASSPATH notion, then writing your own custom data types in Derby is likely to be a challenging project?
In the specific case you describe here, one issue that will arise is that your custom Java code has to be available not only to your client application, but also to the Derby Network Server, which means you will need to be modifying the server's CLASSPATH as well as your application's CLASSPATH.
It's all possible, it's just not a beginner-level project.
To get started with customizing your Derby Network Server, the first topic involves how you are starting it. Here's an overview of the general process: http://db.apache.org/derby/docs/10.11/adminguide/tadmincbdjhhfd.html
Depending on how precisely you are starting the Derby Network Server, you'll possibly be editing the CLASSPATH settting in the startNetworkServer or startNetworkServer.bat script, or you'll be editing the CLASSPATH setting in your own script that you have written to start the server.
If it's a tool like Eclipse or Netbeans which is starting the Derby Network Server, you'll need to dig into the details of that tool to learn more about how to configure its CLASSPATH.
And if you've written a custom Java application to start the Derby Network Server (e.g., as described here: http://db.apache.org/derby/docs/10.11/adminguide/tadminconfig814963.html) then you'd be configuring the CLASSPATH of your custom application.
Regardless, as a basic step, you're going to want to be deploying your custom Java extension classes in the Derby Network Server's classpath, which means you'll want to build them into a .jar file and put that .jar file somewhere that the Derby Network Server has access to, and you'll want to make that build-a-jar-and-copy-it-to-the-right-location process straightforward, so you should integrate it into whatever build tool you're using (Apache Ant?).
And, you'll need to consider Java security policy, because the default security policy will prevent you from trivially loading custom Java classes into your Derby Network Server as that would seem like a malware attack and the Derby Network Server is going to try to prevent that. So study this section of the Security manual: http://db.apache.org/derby/docs/10.11/security/tsecnetservrun.html

Update classes and ressources of a Java Servlet when using Glassfish

In IDEA IntelliJ I have the option to:
Update resources
Update classes and resources
Redeploy
Restart server
If I change some code of a Servlet then I always need to redeploy. Is there another way to "reload" faster to get changes affected?
Check out this IntelliJ WebHelp article: Reloading Classes
However there are limitations:
At the moment due to original limitations of Java SDK the HotSwapping
is possible ONLY if a method body is altered. In all other cases (like
changing method or class signature), the class reload is impossible
and the corresponding error message appears.
For more options you might want to check out what Engineer Dolly suggested in his comment to your question.

Finding a way to load appropriate jars in different OSs as per requirement

This discussion involves getting a way to load different jars in different Operating Systems.
Case Scenario
I am working on a specific OS known as NSK. Its an unix flavour and powers the HP NSK Servers. I am running one of my middleware app ( a java application) on NSK. The requirement is to make this app off-platform. i.e. it must work in other platforms like LINUX or Windows as well.
To implement this, I introduced 1 more jar. Now I need to introduce a logic where-in the JVM must load the appropriate jar at runtime (jar1 on NSK and jar2 on any other non-NSK platform). I used the following logic to implement:
Code:
if (System.getProperty(os.name).equals("NSK"))
load jar1
else
load jar2
The above code works fine until I hit one of the Security exceptions "SecurityException" in getProperty API used above. This tells that the user running the app does not have necessary permission to use getProperty(). So, the above logic goes for a toss here.
Is there any way to tackle this exception and still be able to find out OS details and load the correct jar? Or better, are there any better logic to implement the same?
Please refer the below link for more details about getProperty(..)
http://docs.oracle.com/javase/7/docs/api/java/lang/System.html
Thanks in advance
Regards,
Pabitra
Given that Java is platform independent and only loads the classes you use, I would have one JAR which has everything you need and only load the class which are appropriate for your platform.
Doing what you suggest requires a sub class loader which just add complexity which doesn't appear to be needed.
If you can't access a system property you can actively test your library and see which one work on your system. I am sure there is a method or class which working in one case but not the other or your wouldn't need two sets of code.

Using serviceloader on android

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.

Categories

Resources