Aside from the fact that large parts of .NET are a straight rip-off of Java and that Enterprise Java is years ahead of .NET, there is one thing that .NET addresses that Java never touched. I really like the .NET Globally Assembly Cache (GAC). Java always left JAR management and dealing with shared JARS almost completely up to the developer. It is up to the developer to generate a globally unique name, it is up to the developer to deal with versioning issues, and it is up to the developer to set the classpath. There is very little support for dealing with the problems that arise from shared JARs. Often times I wonder how many copies of XML libraries or Reg Exp libraries are on a system that has many (pre-1.4) Java products installed. Many people are using private copies of everything including the JVM itself. This works fine until people realize that they have to start sharing with other products in the same company or across companies. Everyone ends up implementing the same types of custom solutions. Why do Sys Admins not deal with JARs like they would shared libraries? In the Java world, we often wrap JARs into RPMs and PKGs and then pretend that its not Java. Microsoft's .NET is able to treat assemblies as first class objects to the operating system using the GAC.
Java somewhat addressed this problem with the extensions directory where users can place JRE extension JARS, but this is rather primitive. Perhaps this is more difficult for Java because it can not integrate with the OS as closely as .NET can, but I am not sure that is the only reason. Since Java really took off in the enterprise App Server space, many people were ok with dealing with these issues in their application. (Namely, the app server). But, the fact that small ISVs have to implement a custom solution or just not share at all stinks. I really don't see any reason why something like the GAC could not be implemented for Java.
.NET's Globally Assembly Cache has some pretty nice features for addressing sharing problems in a common way.
@ 10:20 AM PDT