Weblogic application complains about some classes missing, how to debug? - java

I have a rather complex J2EE app I don't have any documentation for and I am trying to get it to run.
I have gotten the ant build script to compile a EAR file that contains a WAR file, but this application even though I get "successfully deployed" on weblogic console is still not working.
There are many required jars missing from the EAR file, hence I get errors about missing classes on the console log when I deploy the app. Sometimes even after I check a particular class is there I still get the error.
What is a best way to debug and get this application running?
Is there any shortcuts in J2EE/Java to "find all dependencies", apps anybody knows to analyze code and find dependencies or anything like that?

Is there any shortcuts in J2EE/Java to "find all dependencies", apps anybody knows to analyze code and find dependencies or anything like that?
Do you mean a compiler? I'm actually semi serious here (even if the compiler won't give you the name of a missing JAR). Indeed, if you are compiling that application successfully with Ant, then you likely have all dependencies required at compile time (you may need more of them at runtime but, well, you'll need to execute the code to identify them). Maybe you just need to add more of them in the EAR during the packaging. Or maybe you need to add more dependencies at the app server classpath level.
In both case, search engines like jarFinder.com or Docjar.com or Jarhoo.com might help you to identify missing JARs and to solve your ClassNotFoundException or NoClassDefFoundError.
You should actually give readers more details about the missing classes, I'm sure people will be able to give you some hints and point you in the right direction.

I know of no easy way to deal with this. If the application provides an ant task build the EAR then the result should be a self-contained deployable application EAR. It is possible that the EAR requires extra libraries to be added to some class path, without documentation it's really hard to know what.
This phrase is, I guess, at the heart of the problem: "Sometimes even after I check a particular class is there I still get the error." Exactly what do you mean?
You are getting a class not found error but you can see the class in the EAR file? If that's the case then things are really difficult, and may well be some kind of classloader issue. I don't know WebLogic at all, but in WebSphere when deploying an application you have a choice of whether to give precedence to JARs in the EAR or to the same JAR in WebSphere itself. Some Applications demand one or the other setting. If there's anything like that in WebLogic then this may be your problem.
Another possible problem is that the app may depend on infrastructure libraries (Eg. XML parsers) that are supplied by WebLogic, but expects a different version that is supplied with the WebLogic version you are using.
Without documentation that the app is supported on the version of WebLogic you are using, I fear you're fighting a long, hard (or even a losing) battle.

I'd assume you managed to get this application put together and compiled in an IDE, maybe Eclipse. Why not simply put all the Jars that you had available at build time, into the EAR?
If you're having to debug this by trial and error, you can look at the list of missing classes and figure out which jars they belong to by Googling for the class names, or maybe you can find them in your IDE too.
If you have a lot of trouble identifying some classes, post the class names (or the error messages) here and someone should be able to tell you where to find the Jar it belongs in.

If you are able to successfully build and deploy the app, but still getting the errors about missing classes, probably some of the jar classes are called through reflection. You may want to search for reflection API calls in the Project through your IDE.
These calls may be something like,
"Class cls = Class.forName(..); cls.newInstance()."
Sometimes even after I check a
particular class is there I still get
the error.
This may be a deployment issue. check the classpath. Some of the jars may be missing from the Classpath.

Is there any shortcuts in J2EE/Java to
"find all dependencies", apps anybody
knows to analyze code and find
dependencies or anything like that?
I'd start by having another go at getting documentation ... or help ... from the original developers, if you can find them. [IMO, people who develop / provide software without any documentation deserve to be bugged incessantly by people asking silly questions.] But I guess you've already tried that.
Then there are the jarfinder.com and other services as mentioned in another answer. (New to me!)
If that fails, I'd try doing a Google search on the FQNs. The chances are that if the missing classes are part of a commonly used library you will hit the Javadocs ... or a posting from someone else with a similar problem to yours.
If the "Google it" approach fails, use the clues in the package naming for the missing classes to try and find where they come from. If they follow the Sun recommendations, the names should map to a company or (real or pseudo-) organization that you can locate by a web search.

Related

Library does not find its own "sublibrary"

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.

Eclipse- Why module-info matters?

I'm very new to java. starting from yesterday! i installed eclipse and imported spring libraries inside it. but a weird problem happened. in import statement there was an error telling The type org.springframework.context.ApplicationContext is not accessible. after running the project another error happened (related to same subject ApplicationContext cannot be resolved to a type).
Anyway! i was confused. it took one day for me. searching forums such as stackoverflow and googling didn't resolve my problem. suddenly i saw a popup message in eclipse suggesting some solutions. ignoring some worthless one of them was adding module to module-info.java file. unbelievably that solved the problem! strangest thing was that i never saw this solution in related forums! and most annoying thing is that what if i never saw that popup? where did i do a mistake? and why this solution doesn't exist on the internet?
Lots of thanks!
Java modules are a new feature of Java 9; they allow you to specify exactly which dependencies you need for your program, hence allowing greater control of the size of your application - no need to bring along library code you don't use. That seems to imply that you need to explicitly say what you want, I guess so that you realise that you are pulling in more modules.
So the reason that you don't see much information about modules in general is that they are comparatively new and doubt that I'm alone in being a long-standing Java developer who has never seen a module-info file!
I wonder whether Eclipse gave you some options when you were creating your project and you inadvertently took an option meaning "yes I want the extra control of doing mocules and I don't mind doing a bit more work."

Using the openNTF Domino API as a dependency in Plugin dev

I have been using the openNTF Domino API (ODA) for a while now and am very happy with it. In fact I am so happy that I want to use it with my own OSGi Plug-ins as dependencies, and I am having trouble with that.
The following is what is going on.
When I just start the plug in and do not use anything from ODA, everything is good. I can select my new library as required in Notes Designer and I can use my classes and all seems well.
The second thing I do is I go into the /META-INF/MANIFEST.MF and I mark org.openntf.domino as a dependency. From what i see, this is the correct plug in because it contains the ODA Document, View, Session etc. Classes that i want to make use of. If I should be using a different plug-in, please tell me.
I go into my class which extends the com.ibm.xsp.library.AbstractXspLibrary and I get a little stuck with the Library.getDependencies(). I am not really certain what to include here to mark my dependency on ODA. I have tried a few different strings, but in the end, I am not even sure if I need to mark it here as a dependency.
I have tried:
"org.openntf.domino"
"org.openntf.domino.xsp"
"org.openntf.domino.xsp.XspLibrary"
I think I tried a few other things but cannot exactly remember what.
The main issue is that I can no longer select my plug-in library in Notes Designer and I cannot use it(obviously). So my question is, how do I correctly add my dependency to other plug-ins installed separately? I will not only be using ODA, but also the ExtLibs.
I am very grateful for any help!
I know that "org.openntf.domino.xsp" depends on "org.openntf.domino.plugin", in the same way I think you want your library to depend on ODA. It also depends on Extension Library. Looking at that, my suggestion is to try:
On plugin.xml, Dependencies tab, add "org.openntf.domino.xsp". This tells it to look for that plugins already on the server, otherwise don't run, in which case I think tell http osgi diag com.myplugin would throw an error. org.openntf.domino.xsp is already dependent on org.openntf.domino.plugin, so that's the only plugin you need as a dependency.
I don't think you'll need to tick "Reexport this dependency". I think you'd do that if you didn't want to install the ODA plugin on the server itself as well. Also, I don't think you'll need to add any exported packages on the Runtime tab.
In getDependencies(), add "org.openntf.domino.xsp.XspLibrary". This loads the XspLibrary class when you load your XspLibrary.

tapestry strange behaviour

Well, at least it seems as tapestry issue.
I'm getting an exception when trying to access a specific page:
org.apache.tapestry.PageNotFoundException:
Page 'ASpecificPage' not found in application namespace.
Seems like some pages are found, and some are not, I'm new to this project, and so far cannot say is there any difference between them.
The error still occurs, even when whole jboss-4 instance, along with the deployed application, is copied from my coworkers' computers and run, whereas they do not experience such problems. Supposedly there is no other application-specific configuration, and it's all contained within the server instance.
Any ideas? Even not Tapestry-related? I tried using same java version, with update number precision, but in vain. Like, where should I start to debug?
EDIT:
I'm new to tapestry, so if anything is missing or just inaccurate, just let me know. Some details:
the application is deployed as war, copied to deploy directory,
unexploded
there are other jars copied as well, not sure if they are relevant
when searching for ASpecificPage, it seems that there is only a java
class (i.e. ASpecificPage.java), and there is missing appropriate
.html file
when searched in code, I found occurences like:
clearPopUp(cycle);
ASpecificPage page=(ASpecificPage) cycle.getPage("ASpecificPage");
page.show(cycle, ASpecificPage.TAB_2);
Any other details needed?

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