Java-Gaming.org Hi !
Featured games (90)
games approved by the League of Dukes
Games in Showcase (777)
Games in Android Showcase (231)
games submitted by our members
Games in WIP (856)
games currently in development
News: Read the Java Gaming Resources, or peek at the official Java tutorials
 
    Home     Help   Search   Login   Register   
Pages: [1]
  ignore  |  Print  
  Load a java Class During Runtime, from outside the .jar.  (Read 2939 times)
0 Members and 1 Guest are viewing this topic.
Offline Andre Lopes
« Posted 2014-01-01 21:31:03 »

Hey guys, im trying to load a class from otuside the .jar during runtime, but im being unable to.
Yes Opiop, i googled it the whole day, tried several methods, read a bunch of topics, but i get the same error.

Can anyone me guide me or give me any tip of some sort?


i have this class inside my jar
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
public class Script {

    public void Script()
    {
       
    }
   
    public void script(Player player, BitmapFont simpleWhiteFont) {

        int playerPosX = (int) (player.getX() / 16);

        int playerPosY = (int) ((player.getY() + player.getHeight() / 2) / 16); //(getY() + getHeight() / 2) / 16

    }
}




I have this class below in D:\


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
public class test extend Script
{

public String className = "script";


  public void script(Player player, BitmapFont simpleWhiteFont) {

       int playerPosX = (int) (player.getX() / 16);

       System.out.println("Player X Position : " + playerPosX );

    }

}


I tried this below:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
  private void loadScript(String scriptLocation) {

        // Create a File object on the root of the directory containing the class file
        File file = new File("D:/");

        try {
            // Convert File to a URL
            URL url = file.toURI().toURL();      // file:/c:/myclasses/
            URL[] urls = new URL[]{url};

            // Create a new class loader with the directory
            ClassLoader cl = new URLClassLoader(urls);

            // Load in the class; MyClass.class should be located in
            // the directory file:/c:/myclasses/com/mycompany
            Class cls = cl.loadClass("test");
            script = (Script) cls.newInstance();
            script.script(player, simpleWhiteFont);
           
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


Quote
java.lang.ClassNotFoundException: test
   at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
   at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
   at java.security.AccessController.doPrivileged(Native Method)
   at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
   at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
   at br.views.levels.Level_Loader.loadScript(Level_Loader.java:70)
   at br.views.levels.Level_Loader.<init>(Level_Loader.java:51)
   at br.views.MenuView$3.clicked(MenuView.java:169)
   at com.badlogic.gdx.scenes.scene2d.utils.ClickListener.touchUp(ClickListener.java:85)
   at com.badlogic.gdx.scenes.scene2d.InputListener.handle(InputListener.java:57)
   at com.badlogic.gdx.scenes.scene2d.Stage.touchUp(Stage.java:345)
   at com.badlogic.gdx.backends.lwjgl.LwjglInput.processEvents(LwjglInput.java:303)
   at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:200)
   at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:114)
Java Result: -1
Offline HeroesGraveDev

JGO Kernel


Medals: 382
Projects: 11
Exp: 4 years


┬─┬ノ(ಠ_ಠノ)(╯°□°)╯︵ ┻━┻


« Reply #1 - Posted 2014-01-01 21:38:02 »

I'm not entirely sure how to do this, as I didn't write the code (Longor1996 did), but here's the code for loading Paint.JAVA plugins.

It only works with class files inside external .jars though, but there should be a way around that.
Maybe it'll help.

Yes Opiop, i googled it the whole day, tried several methods, read a bunch of topics, but i get the same error.

Roll Eyes

(EDIT: You shouldn't be using
File("D:\")
because that will only work on Windows, and only if you have permission for that folder/drive. Use something more cross-platform and security-compatible like
System.getProperty("user.home")
)

Offline Longor1996

JGO Wizard


Medals: 115
Projects: 2
Exp: 8 years


The cake is probably a lie.


« Reply #2 - Posted 2014-01-01 22:39:40 »

For the sake of order and easier usage, you should go and just use the same Code as Paint.JAVA uses, as the Plugin-Code itself (which I did write) is Open-Source under the "DoWhatTheF***YouWantToThePublic"-License. You may need to change the names of a couple of classes though.

Also, Java can't simply access any file that lies on the root level of any storage device. (Security problems and Co.)
You are making it even harder because you are trying to load a no-package and no-jar-packed class-file.

Read the plugin-loader code, understand it, then copy/implement it in your application.

Have a nice day.

- Longor1996

The cake is probably a lie... but it's a delicious lie!
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline Opiop
« Reply #3 - Posted 2014-01-01 23:03:54 »

Offtopic (sort of) but don't call me out for asking you to Google things first. I realize some issues (such as this) cannot be solved using Google, so that's fine. But some issues can be solved via Google. Don't call me out on that.
Offline HeroesGraveDev

JGO Kernel


Medals: 382
Projects: 11
Exp: 4 years


┬─┬ノ(ಠ_ಠノ)(╯°□°)╯︵ ┻━┻


« Reply #4 - Posted 2014-01-01 23:26:43 »

Oh and by the way, I see what the problem with you code is.

You aren't providing the actual path to load the class from.
You're just pointing it at 'D:\' when the files you need are in a subdirectory.

But that is irrelevant as it's much easier just to take the Paint.JAVA code and adapt it for your purpose.

(Note: To clear things up, the code is licensed under the GPL, but that only applies if you directly use it. The ideas behind it are free for obvious reasons)

Offline Andre Lopes
« Reply #5 - Posted 2014-01-02 03:20:46 »

Oh and by the way, I see what the problem with you code is.

You aren't providing the actual path to load the class from.
You're just pointing it at 'D:\' when the files you need are in a subdirectory.

But that is irrelevant as it's much easier just to take the Paint.JAVA code and adapt it for your purpose.

(Note: To clear things up, the code is licensed under the GPL, but that only applies if you directly use it. The ideas behind it are free for obvious reasons)

Hi guys, thanks for the replies.
Well Opiop, i understand.

Hero,
The class must be inside a .jar to be loaded? I was planning to load the .class directly.
Offline HeroesGraveDev

JGO Kernel


Medals: 382
Projects: 11
Exp: 4 years


┬─┬ノ(ಠ_ಠノ)(╯°□°)╯︵ ┻━┻


« Reply #6 - Posted 2014-01-02 03:32:23 »

It doesn't have to be, AFAIK, but the code I pointed you to only works with .jar files, and when Longor tried to implement it for classes directly it didn't work.
If you want more info, you'll have to ask him.

But anyway, making a jar from a class file is easy:

1  
jar -cfM [jarname] [list of class files]

Offline Andre Lopes
« Reply #7 - Posted 2014-01-02 04:46:52 »

Well it worked.
Kinda.
If i use reflection, it works, but if i try to cast it, it fails.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
  private void loadScript() {

        //D:\resources\jarTest\dist
        // Create a File object on the root of the directory containing the class file
        File file = new File("D:\\resources\\jarTest\\dist\\ArcherScript0.1.jar");

        try {
            // Convert File to a URL
            URL url = file.toURI().toURL();      // file:/c:/myclasses/
            URL[] urls = new URL[]{url};

            // Create a new class loader with the directory
            ClassLoader cl = new URLClassLoader(urls);

            Class scriptLoaded = Class.forName("br.scripts.LevelScript", true, cl);

            Class<? extends Script> scriptClass = scriptLoaded.asSubclass(Script.class);
           
            script = scriptClass.newInstance();
           
           
//            Object[] paramObject = new Object[]{file};
//            Class<?>[] paramType = new Class[]{};
//
//            Method method = scriptLoaded.getMethod("test", paramType);
//            method.invoke(scriptLoaded.newInstance(), null);

            script.script(player, simpleWhiteFont);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }


java.lang.ClassCastException: class br.scripts.LevelScript



In the outside jar, i mean , ArcherScript0.1.jar i have this classes :

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
package br.scripts;

/**
 *
 * @author André Vinícius Lopes
 */

public class LevelScript extends Script {

   
   
    public void test() {
        System.out.println("Test!");
    }
}


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
package br.scripts;

import com.badlogic.gdx.graphics.g2d.Sprite;

/**
 *
 * @author André Vinícius Lopes
 */

class Player extends Sprite{
}


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
package br.scripts;

import com.badlogic.gdx.graphics.g2d.BitmapFont;

/**
 *
 * @author André Vinícius Lopes
 */

public class Script {

    public void Script() {

    }

    public void script(Player player, BitmapFont simpleWhiteFont) {

    }

}




In my game .jar, the one im loading the class, i have this :

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
package br.views.levels.scripts;

import br.player.Player;
import com.badlogic.gdx.graphics.g2d.BitmapFont;

/**
 *
 * @author André Vinícius Lopes
 */

public class Script {

    public void Script()
    {
       
    }
   
    public void script(Player player, BitmapFont simpleWhiteFont) {

        int playerPosX = (int) (player.getX() / 16);

        int playerPosY = (int) ((player.getY() + player.getHeight() / 2) / 16); //(getY() + getHeight() / 2) / 16

    }
}






What am i doing wrong!?
Offline HeroesGraveDev

JGO Kernel


Medals: 382
Projects: 11
Exp: 4 years


┬─┬ノ(ಠ_ಠノ)(╯°□°)╯︵ ┻━┻


« Reply #8 - Posted 2014-01-02 04:57:56 »

I've provided an example of working code already.

I have limited knowledge of this stuff anyway, so if you're not going to have a look at the code and try to adapt it for your purposes, then I can't really help you with any problems you have.

I don't know exactly what you're doing wrong, but I can tell you that it's most likely still in you script-loading code.

Offline Andre Lopes
« Reply #9 - Posted 2014-01-02 05:06:02 »

I've provided an example of working code already.

I have limited knowledge of this stuff anyway, so if you're not going to have a look at the code and try to adapt it for your purposes, then I can't really help you with any problems you have.

I don't know exactly what you're doing wrong, but I can tell you that it's most likely still in you script-loading code.

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
 // Try to load the class!
                                try
                                {
                                        //Load
                                        Class<?> c = cl.loadClass(className);
                                       
                                        // Check if the class is assignable from PluginBase (Is it a plugin?)
                                        if(Plugin.class.isAssignableFrom(c))
                                        {
                                                // The class is a Plugin main-class!
                                                // Cast it into the right type now...
                                                Class<? extends Plugin> pluginClass = c.asSubclass(Plugin.class);
                                               
                                                // Then try to instantiate it...
                                                try
                                                {
                                                        Plugin newPluginInstance = pluginClass.newInstance();
                                                        this.loadedPlugins.add(newPluginInstance);


1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
 try {
            // Convert File to a URL
            URL url = file.toURI().toURL();      // file:/c:/myclasses/
            URL[] urls = new URL[]{url};

            // Create a new class loader with the directory
            ClassLoader cl = new URLClassLoader(urls);

            Class scriptLoaded = Class.forName("br.scripts.LevelScript", true, cl);

            Class<? extends Script> scriptClass = scriptLoaded.asSubclass(Script.class);
           
            script = scriptClass.newInstance();



I did read the code.
Some articles claims i must use an interface instead of extend.
Still i just wanted a 2nd opinion.
I can use Reflection but i will keep trying find a solution.
Games published by our own members! Check 'em out!
Legends of Yore - The Casual Retro Roguelike
Offline HeroesGraveDev

JGO Kernel


Medals: 382
Projects: 11
Exp: 4 years


┬─┬ノ(ಠ_ಠノ)(╯°□°)╯︵ ┻━┻


« Reply #10 - Posted 2014-01-02 05:26:13 »

What about the bit before it:

1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
// List Entries
         Enumeration<JarEntry> e = jarFile.entries();
         
         // Load JAR?
         URL[] urls = {new URL("jar:file:" + possiblePluginRoot.getAbsolutePath() + "!/")};
         
         // This should not be closed (or should it?)
         URLClassLoader cl = new URLClassLoader(urls);
         
         while(e.hasMoreElements())
         {
            JarEntry je = e.nextElement();
           
            if(je.isDirectory() || !je.getName().endsWith(".class"))
            {
               continue;
            }
           
            // Get the actual class-name!
            String className = je.getName().replace(".class", "");
            className = className.replace('/', '.');
           
            // Try to load the class! (the start of the bit you pasted)

Pages: [1]
  ignore  |  Print  
 
 

 
hadezbladez (337 views)
2018-11-16 13:46:03

hadezbladez (180 views)
2018-11-16 13:41:33

hadezbladez (336 views)
2018-11-16 13:35:35

hadezbladez (83 views)
2018-11-16 13:32:03

EgonOlsen (2177 views)
2018-06-10 19:43:48

EgonOlsen (2206 views)
2018-06-10 19:43:44

EgonOlsen (1378 views)
2018-06-10 19:43:20

DesertCoockie (2011 views)
2018-05-13 18:23:11

nelsongames (1655 views)
2018-04-24 18:15:36

nelsongames (2300 views)
2018-04-24 18:14:32
Deployment and Packaging
by mudlee
2018-08-22 18:09:50

Java Gaming Resources
by gouessej
2018-08-22 08:19:41

Deployment and Packaging
by gouessej
2018-08-22 08:04:08

Deployment and Packaging
by gouessej
2018-08-22 08:03:45

Deployment and Packaging
by philfrei
2018-08-20 02:33:38

Deployment and Packaging
by philfrei
2018-08-20 02:29:55

Deployment and Packaging
by philfrei
2018-08-19 23:56:20

Deployment and Packaging
by philfrei
2018-08-19 23:54:46
java-gaming.org is not responsible for the content posted by its members, including references to external websites, and other references that may or may not have a relation with our primarily gaming and game production oriented community. inquiries and complaints can be sent via email to the info‑account of the company managing the website of java‑gaming.org
Powered by MySQL Powered by PHP Powered by SMF 1.1.18 | SMF © 2013, Simple Machines | Managed by Enhanced Four Valid XHTML 1.0! Valid CSS!