How to get jar class is coming from - java

I am currently working on an API for a server software so users can extend my software by programming plugins for it instead of modifying the software themselves, and allow other users without programming knowledge to easily change the software by adding these plugins. So far, everything is working fine. But, I am running into a problem with configuration.
You see, each plugin has a plugin.yml file stored with these 4 attributes:
Main: The main class is stored here
Name: This is where the plugin name is stored
Version: This is where the plugin version is stored
Author: This is where the plugin author is stored
Now, in order for the plugin to print something to the console, they use a function called: this.getServer().getLogger().info("MESSAGE); (They extend another class for plugins, thats why they use "this" instead of another class to log)
But, I do not have any idea on how to get which plugin is which when they are calling the function. I have a ArrayList of PluginSessions which event handlers use to cycle through to run Event Functions.
My solution is to get the jar from which a class is being called so I can then get the plugin.yml from there. But, I have NO idea on how to get that, I have tried using Class.forName(); and some other code. But because the class is non-existent within the jar/project running the code, It will throw a ClassNotFoundException.
Does anyone here know how to get the jar from which a class is coming from without using Class.forName()? Thanks! -Trent

Take a look at Class.getResource.
If you call MyClass.getResource("plugin.yml") (or "/plugin.yml" with leading slash, I forget) you get back a file URL pointing to the plugin.yml file in the same jar as MyClass. (Or null if the path is wrong or the jar doesn't contain a "plugin.yml" file.) You can then open an InputStream to that resource. In a plugin framework you may want to use myPluginInstance.getClass().getResource.

Assuming jar for 'PluginSessions' is already added in you classpath by eclipse then you can try the following trick -
Select/highlight PluginSessions by double clicking on it
Now press CTRL+SHIFT+T
A dialog named Open Type is appeared. Here you found from where the PluginSessions class is coming from. If you have more than one jar containing PluginSessions class than you have a list of them.
To benefited from this CTRL+SHIFT+T trick you need to add all of your jar need by the project to be added in your classpath.

Related

Could not find or load main class Swing Java

Error: Could not find or load main class jewelleryerpapplication.GUI.ERPMainMenu
Java Result: 1
Actually i am using Net Beans 7.1 and in that i am continuosly getting the same error but un able to get the solution for that even after installing the latest update for that. The solution which i got from some body that create new project and copy the source and library foldes in that Project from the previous which generate the above error. this solution works for me but i need some simpler solution for this problem.Lot of thanks in advance.
Don't Forget To Give UpVote It If It Helps.
Right click on project node, go to Set configuration, select the main class for your application. Then clean and build.
Even if this doesn't solve your problem, then delete the Netbeans cache by deleting the (index) folder
User\.netbeans\6.9\var\cache\index\
I think that the following is happening:
If this is a third party application, you have not included some jar files on your class path;
Or, (which in my opinion is the most likely) you do not have a method which has this signature: public static void main(String[] args). This method defines the main entry point for your application, not having it might cause that error when you try and run the project. To my knowledge, Netbeans creates a main class with such a method automatically whenever you create a new project. This might be the reason why you are not having this exception when you create a new Project and throw everything in it.
You might be having an issue with Netbeans itself. You can start by either checkin gout this previous SO thread in which a similar (I think) issue is being discussed, or else, as a final resort, you might want to remove Netbeans and all its files, and install an earlier version. You can also try and see if you get the same issue if you use a different IDE such as Eclipse.
the solution is,right click your package in netbeans,go to properties,source now go to the jre option and choose your version,the programme will now run.

Cannot find the "GoogleAccountManager" in the google plus example

While trying the google plus API example from the project site I'm completely stuck with one import:
import com.google.api.client.googleapis.extensions.android2.auth.GoogleAccountManager;
This thing just doesn't seem to exist in the project.
The sample is a read-made Eclipse project I imported, and to be sure I checked if the massive amount of .jar's in the /lib directory are added to the build path. They are, I can see them listed in the Referenced Libraries part in my Eclipse project.
I can find mentions of com.google.api.client.googleapis.extensions.android2.auth but there just doesn't seem to be any GoogleAccountManager class around.
Several possibilities I have come up with, but can't find out which is it, let alone find a solution to them:
I have not set up my project correctly. I doubt it, but completely possible. This would mean that the example has a broken project set-up and/or I managed to not import all libraries?
The class or package or something like that is renamed // named differently. This would mean the example is broken out of the box, and that I still need to find the correct class (and change the import + calling code to that)
Something else :D
The following are the contents of the libs directory as you can also browse on the project page . Notice that it does containt google-http-client-extensions-android2-1.6.0-beta.jar
google-api-client-1.6.0-beta-sources.jar
google-api-client-1.6.0-beta.jar
google-api-client-extensions-1.6.0-beta-sources.jar
google-api-client-extensions-1.6.0-beta.jar
google-api-client-extensions-android2-1.6.0-beta-sources.jar
google-api-client-extensions-android2-1.6.0-beta.jar
google-api-services-plus-v1-1.3.0-beta-sources.jar
google-api-services-plus-v1-1.3.0-beta.jar
google-http-client-1.6.0-beta-sources.jar
google-http-client-1.6.0-beta.jar
google-http-client-extensions-1.6.0-beta-sources.jar
google-http-client-extensions-1.6.0-beta.jar
google-http-client-extensions-android2-1.6.0-beta-sources.jar
google-http-client-extensions-android2-1.6.0-beta.jar
google-http-client-extensions-android3-1.6.0-beta-sources.jar
google-http-client-extensions-android3-1.6.0-beta.jar
google-oauth-client-1.6.0-beta-sources.jar
google-oauth-client-1.6.0-beta.jar
gson-1.7.1.jar
guava-r09.jar
On the first page is a link to updated Google plus libraries google-plus-java-starter_v5.zip
Updated Link: google-plus-java-starter_v5.zip
It contains android/libs/google-api-client-extensions-android2-1.6.0-beta.jar, which contains GoogleAccountManager class.
As this is an extension it probably needs other jars too.
(summary of comments)
Manually adding /libs/google-api-client-extensions-android2-1.6.0-beta.jar to the build path and verifying that it is in the Referenced Libraries fixes the problem. It is unknown (to me (Nanne)) why this doesn't happen automagically when adding the libraries, but there you are.
Right-click on Project, select Properties->Java Build Path->Order and Export Tab->click on checkbox for “Android Private Libraries”. That worked for me.

How do I open an included java class(for example JButton) in IntelliJ IDEA 10?

I want to be able to open up the JButton class and see the code inside it. The reason is because I want to override one of the methods, but I want to make sure I include all the functionality that that method normally has. Also, it'd be a good way to learn. I know I can do it when I've had errors by clicking on the class in the error messages. But any ideas on how to bring it up normally?
Go To | Class (Ctrl+N), type JButton (Include non-project classes checkbox will be enabled automatically if no such classes are found in your project).
If you already have JButton usage in your code, you can navigate to its source using Ctrl+B while the caret is on it.
Of course you need sources attached to the JSDK, but it should be fine by default (as JSDK installation has sources on most platforms). If you are on Mac, you will have to download them separately and attach to the JSDK configuration in File | Project Structure | SDKs.
If you have sources just press Ctrl+B on JButton, if you have no, download sources, add to configuration of project and press the same combination
Download the Java Source code here: http://www.oracle.com/technetwork/java/javase/downloads/index.html
Also don't forget about the super keyword which you can use to interact with the extended class
You need to download the Java source code. If you're using Java 1.6, for example, you can go here to get it. Unzip it somewhere on your local disk.
When I need to look at the source code of a Java class I then navigate to the source class and drag it into my IDE.
If you want to ensure you get all the functionality of the original method, call the original method as part of your method. Using super gives you a reference to the overridden method, e.g. super.overridden();. Don't just copy the Java source into your method.

tomcat - reload classes dynamically

I have a folder with a lot of .class files. This classes are updated from 'app 1'. And there is 'app 2' that loads those classes dinamically.
And the problem is....
'app 2' uses a class file, 'app 1' update that file, then 'app 2' needs again the class but it seemes to keep and to use a copy of the older class.
so, I checked the folder and the class was updated successfully, I tried to reload 'app 2' but it keeps using the older class.
Only if I restart tomcat 'app 2' reads the new class.
Why is that?
I'm allowed to reload 'app 2' but, in production enviroment, I cant restart tomcat.
Its very important in my job, I appreciate any idea.....
I'm using a clean installation of tomcat6 and I load the class files with:
Class.forName(<classname>).newInstance()
thx a lot
The problem is that the runtime has already loaded the old classfile into the classloader being used by the code that wants to use the modified class. You'd have to find a way to get the classloader to refresh its class contents from disk in order to achieve what you want. This is why Class.forName() isn't working : it's accessing the already loaded (and cached) version of the class. Alex R is right that you should try to restructure your code to separate your classes for these two projects. But, if you're dead set on trying to reload that class and keep things they way they are, you can try experimenting with Classloader.defineClass() and loading the new version of the class from its .class File into a byte[], then passing that byte[] to Classloader.defineClass(). You'll most likely want to use the context classloader associated with your application by Tomcat (rather than the top level Tomcat classloader). There's documentation distinguishing between the two in the Tomcat project documentation.
Default behaviour is that classes are cached by the ClassLoader that loaded them. If you do: Class.forName('MyClass') two times in a row, you will only load the class the first time.
To reload a class, you need not only to release any reference you already have to any instance of this class, but also any reference you have to the ClassLoader that loaded it. Only then can you be sure the whole class can be garbage collected (or you will end up with memory leaks - a perennial problem in reloading webapps).
You may be able to extends ClassLoader and alter the caching behaviour.
You are right!
This is a great explanation with an example about Alex´s idea
I think that you should try to separate classes for these 2 applications. Try first to create 2 identical directories. One for app1, second for app2. If this solves your problem pack your classes into jar and keep just 2 duplicate jar files. I think that the problem is not in java but in filesystem. I believe that you are using windows. If so probably try to do what you are doing now in linux (unless it is irrelevant for your company).

Java Reflection not working on my system - working for team members

I am working on a team project in Java. One requirement is that we dynamically populate a drop-down menu of all classes that implement a certain interface. New classes can be added after compile time. To accomplish this we are using reflection.
Problem: All of the drop-down menus are blank on my system. I cannot for the life of me figure out why they are not populating. All other 5 team members have it working on their system.
Things I tired that didn't work:
1) Installing most recent eclipse (galileo) because rest team was using it
2) Re-install most recent java release (jdk1.6.0-17 and jre6)
3) Check PATH and JAVA_HOME variables
Any thoughts as to what else I can try or if something I did should have solved it and didn't? It is driving me crazy.
Edit:
I should have been clearer that we are developing in a team. We are using SVN for version control and we are all running the exact same source code. I even tried checking out a fresh copy of the entire tree from SVN, but I had the same issue with reflection on my system while it worked for teammates.
The team created an executable jar and that ran on everyone's system fine except for mine. Everything worked for me except the reflection bit.
You need to debug your application. This means you have to systematically explore possible causes of the problem. Here are some things that come to mind:
Could your GUI be failing rather than reflection? What if you output with System.out.println() rather than your menu?
Is your reflection code throwing an exception, and are you ignoring it?
Is your reflection code actually being called? Toss a println() in there to be sure!
Is the test for the interface suffering from a typo or similar error that's causing it to fail? Try finding classes that implement Serializable instead!
Is your reflection test running in the main thread and trying to update your GUI? You need to use SwingUtilities.invokeAndWait to get an update to the Swing worker thread.
You're working with Eclipse; Eclipse has a fantastic debugger. Set a breakpoint near where your main action is and then single step through the code.
PATH and JAVA_HOME won't help. PATH only affects dynamically-linked libraries ("native code"). JAVA_HOME is a scripting variable that happens to be used by some Java-based utilities like Ant and Tomcat; it means nothing to the Java runtime itself.
You need to be investigating the classpath, which should be specified by the -classpath option to the java command, in the Build Path in your Eclipse project properties, or in the Class-Path attribute of the main section of a JAR file if you're launching java with the -jar option.
From within your code, you should be able to list the contents of your classpath by examining the system property, "java.class.path"
System.out.println(System.getProperty("java.class.path"));
Problem solution:
Classpath leading to source code must have no spaces in it.
I am running windows XP and, for whatever reason, if the classpath that leads to the jar file or source code that is using reflection has any spaces in it, then the reflection fails.
I took the jar file that works for the rest of my team and ran it from C:\ on my system and the reflection worked perfectly fine.
I do not know why this is so please comment if you know what is happening.
Might be a long shot, but look for differences in security settings for you and your team mates. Article describing more details http://www.ibm.com/developerworks/library/j-dyn0603/ heading "Security and reflection"

Categories