# Neue "Klassen" zur Laufzeit erzeugen !nicht Instanzen



## Romsl (26. August 2005)

Hi,

besteht die Möglichkeit zur Laufzeit neue Klassen zu erzeugen. Diese Klasse sollte von einer Basisklasse abgeleitet sein. Es ist eine leere implementation, nur abgeleitet.

Danke


----------



## Thomas Darimont (26. August 2005)

Hallo!

 Dynamic CGLib Proxys ;-) (Wenn du dynamisch Klassen erzeugen willst, die von abstrakten Klassen erben) oder JDK/CGLib Proxies wenn du immer (ein) spezielle(s) Interfaces implementieren willst.

 Gruß Tom


----------



## Romsl (26. August 2005)

Danke,

werds mal mit CGLib versuchen, das hört sich richtiger an. Hast du evtl ein Beispiel das nur von einer Klasse ableitet. Den Klassennamen sollt ich selbst vergeben können.

Danke


----------



## Thomas Darimont (26. August 2005)

Hallo!

      Schau mal hier:

```
package de.tutorials;
      
      import java.lang.reflect.Method;
      
      import net.sf.cglib.proxy.Enhancer;
      import net.sf.cglib.proxy.MethodInterceptor;
      import net.sf.cglib.proxy.MethodProxy;
      
      public class CglibExample {
      
      	/**
      	 * @param args
      	 */
      	public static void main(String[] args) {
      		AbstractFoo foo = generateCGLIBProxyInstanceFor(AbstractFoo.class);
      		System.out.println(foo.getClass());
      		foo.bar();
      	}
      	
      	private static AbstractFoo generateCGLIBProxyInstanceFor(Class<AbstractFoo> superClazz) {
      		
      		Enhancer enhancer = new Enhancer();
      		enhancer.setSuperclass(superClazz);
      		enhancer.setCallback(new MethodInterceptor(){
 			public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
  				String name = arg1.getName();
      				if("bar".equals(name)){
 					System.out.println("bar");
      				}
      				return null;
      			}
      		});
      		
      		return superClazz.cast(enhancer.create());
      	}
      
      	static abstract class AbstractFoo{
      		public abstract void bar();
      	}
      }
```
      Habe die cglib-nodep-2.1_2.jar aus dem Springframework genommen...
      Ich denke den Namen der generierten Klasse kann man nicht beinflussen...
      aber ich schau mir das mal noch etwas genauer an...

    //Edit... könnte man hinbekommen, indem man die NamingPolicy "passend" implementiert...

```
enhancer.setNamingPolicy(new DefaultNamingPolicy(){
    			@Override
 			public String getClassName(String arg0, String arg1, Object arg2, Predicate arg3) {
    ...
```
 
     Mit einem JDK DynamicProxy sähe das so aus... (Geht nur mit Interfaces...):

```
package de.tutorials;
     
     import java.lang.reflect.InvocationHandler;
     import java.lang.reflect.Method;
     import java.lang.reflect.Proxy;
     
     public class JDKDynamicProxyExample {
     
     	/**
     	 * @param args
     	 */
     	public static void main(String[] args) {
     		
 		IFoo foo = (IFoo)Proxy.newProxyInstance(IFoo.class.getClassLoader(),new Class[]{IFoo.class},new InvocationHandler(){
 			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
     				
 				String methodName = method.getName();
     				
 				if("bar".equals(methodName)){
 					System.out.println("bar");
     				}
     				
     				return null;
     			}
     		});
     		
     		foo.bar();
     		
     		
     	}
     	
     	static interface IFoo {
     		void bar();
     	}
     
     }
```
 
   //Edit2 ... habe jetzt mal das Topic "*Neue "Klassen" zur Laufzeit erzeugen !nicht Instanzen* 
 " richtig gelesen. Das ginge IMHO auch über CGLib bzw. asm... du kannst die Klasse in ein byte[] überführen und dann auf die Platte schreiben.
   Dafür mache ich aber jetzt kein Beispiel... 

   Denke du solltest du mal zusätzlich noch dies hier anschauen...: http://www.tutorials.de/tutorials188990.html&highlight=JavaAssist

   Btw. was willst du eigentlich machen...?

       Gruß Tom


----------



## Romsl (27. August 2005)

Hi Thomas,

ich möchte mit hibernate dynamisch Tabellen erzeugen. Die Daten eines Objektes sollen dann in die jeweilige Tabelle gespeichert werden. Mein Problem dabei ist, dass es sich für alle dyn Tabellen um das selbe bo handelt.
Mein Ansatz wäre jetzt für jede dyn Tabelle eine neue Klasse (abgeleitet von der Standardklasse) erzeuge um somit auf diese bestimmte Tabelle zu mappen.

Gruß

Romsl


----------



## Thomas Darimont (27. August 2005)

Hallo!

 hmmm, wie wär's denn, wenn du einfach nur die Hibernate Mappings (XML Dokument) zur Laufzeit erzeugst und dann die Hibernate Tools bemühst (hbm2java / hbm2dll) um das passende Java Model und Datenbankschema zu erzeugen...?

 Gruß Tom


----------



## Romsl (27. August 2005)

Hi,

das wäre evtl. eine Möglichkeit. Wo werden die Klassen aber dann abgelegt? Werden überhaupt_Klassen physisch erzeugt oder nur virtuell in der JVM gehalten?

Es ist ja so, dass schon bo bestehen, aber diese nicht nochmal erzeugt werden müssen.

Gruß Romsl


----------



## Thomas Darimont (27. August 2005)

Hallo!



> das wäre evtl. eine Möglichkeit. Wo werden die Klassen aber dann abgelegt? Werden überhaupt_Klassen physisch erzeugt oder nur virtuell in der JVM gehalten?


Bei Verwendung von Dynamic Proxies (JDK Proxies oder cglib Proxies) bestehen die Klassen nur zur Laufzeit in der JVM. Bei der Verwendung der Hibernate Tools werden die Klassen auch auf dem Filesystem abgelegt. Die dabei generierten Klassen müsste man jedoch u.U. dynamisch zum Classpath hinzufügen.

Gruß Tom


----------



## Romsl (29. August 2005)

Kann ich bei einem id generator (foreign) auf eine Property die in einer dynamic-component definiert ist zugreifen?


----------

