20

Is it possible to import and use two different classes with the same name and package in java?

For example, let's say I have two classes named "com.foo.Bar" that are slightly different. I'd like to be able to use both, but I have a restriction (because of stupid reflective crap) that forces me to keep the names and packages the same.

Is there some feature of java that would allow me to import and isolate each of these classes?

To elaborate, I changed my avro schemas in ways that they shouldn't have ever been changed (oops!) and now I'd like to go back and change the old avro files that can't be read with my new schema into files that can be read by my new schema. Avro seems to force you to use a specific class and package name to load the files.

guidoism
  • 7,820
  • 8
  • 41
  • 59
  • It is a compile-time error if the name of a top level type appears as the name of any other top level class or interface type declared in the same package. – roshan Nov 02 '13 at 08:20

8 Answers8

13

Yes there is. You would need to implement your own Classloader and play some games to be able to access both during runtime.

I'm sure this is possible, because I ran into a very hard to debug issue where someone had a weird Classloader in their product that was messing up loading libraries and providing 2 different versions of the same file from 2 different versions of the library.

However, this sounds like an INCREDIBLY bad idea. I'd go back and find a different way of fixing your issue. This will only bring you heartache in the long run. Heck, it probably already is, as you investigate class loaders.

EDIT: To be specific, you cannot "import" both. But you can access both at runtime.

rfeak
  • 8,124
  • 29
  • 28
  • 1
    I think you just need as many separate class loader instances (one of which can be the bootstrap class loader) as you want to have references to the eponymous classes. You don't actually need to write your own class loader for that. – Mishax Nov 24 '12 at 04:21
8

No, java packages are used precisely to avoid that problem.

João Silva
  • 89,303
  • 29
  • 152
  • 158
  • 1
    I do not think the wrapper class idea will work. Let the 2 identically named classes be C1 and C2; and their respective wrappers W1 and W2. The class loader will (1) load W1 which will cause it to (2) load C1. Then the class loader will (3) load W2. It will think it already loaded C2 (because of identical names) and your W2 class will wrap C1. – emory Jul 29 '11 at 23:12
2

Yes it is. It does require you to make your own ClassLoader, though

I had made a demo of that on github to!

brunoais
  • 6,258
  • 8
  • 39
  • 59
1

If you really most definitely must do something like this, you can achieve it by using different classloaders and possibly reflection.

This is not the way Java works and it's not allowed on purpose - you shouldn't be doing stupid things which will screw up things for you.

carlspring
  • 31,231
  • 29
  • 115
  • 197
0

There are no namespaces in Java, only in C#, so I assume you mean packages. There can only be one fully qualified name per project.

Oscar Gomez
  • 18,436
  • 13
  • 85
  • 118
0

Technically it can be done using some low-level trickery such as rewriting the byte-level code. As far as I know the different java crypter/encrypters work like that - they have a lot of classes called A.class B.class C.class etc.

LordDoskias
  • 3,121
  • 3
  • 30
  • 44
  • It doesn't have to be low-level or trickery. Separate class loader instances is the way to go. – Mishax Nov 24 '12 at 04:23
0

It sounds to me like you need to define your method signatures in an interface called com.foo.Bar. Then provide two different concrete implementations of the interface (say, com.foo.DefaultBar, and com.foo.SpecialBar). This way, you can program against the interface type, and switch between the two different implementations as required.

Can you elaborate on what you mean by "reflective crap"? That may provide insight into your exact issue.

Don't mess with the class loader or any other low level trickery. The best way to solve such issues it to have a clear design in the first place that anyone can understand.

Scott
  • 2,233
  • 2
  • 15
  • 8
  • 1
    We changed our avro schema in ways we should have so I'm trying to write a hadoop job to fix the files that are using the old schemas. Avro seems to force you into using the same class and package name. – guidoism Jul 29 '11 at 23:49
0

As already mentioned writing your own Classloader or additionally use a OSGi framework like Equinox which does the classloading for you

Omnaest
  • 3,096
  • 1
  • 19
  • 18