(a) How you structure larger applications into projects (assemblies) is largely your own problem. If you have a component that's intended to be used from different projects, then it sometimes makes sense that it gets its own project as well. However, you can just as well cross-include the source file if you want. There aren't that many things that explicitly require separate assemblies.
(b) Debug symbols have to be there for you to be able to have source-level debugging, of course. You can always debug the assembly code, of course. For Microsoft's tooling, PDB files are the debug symbols that link the assembly code to the source code. Other tools sometimes embed debugging information in the binaries. And if this information isn't there, you can't have source debugging either.
(c) No one's forcing you to use NuGet, although I wonder what you particular problems are with it.
(a) it's usually a problem you inherit when you join a team/project and you didn't make the choices about it but for some reason there is 200 .sln files and impossible to open the entire project in a single .sln file. Well, I've had that once but my current situation is better than that but still somewhat problematic.
(b) debug symbols could just be included in the compilation unit and optionally stripped out using a flag when you compile. There isn't a need for it to be in a separate file. A lot of fun times attaching DnSpy to something to half-ass debug it through a decompiler because there was no .pdb and you can't debug without it. Just painful. Wish they never split the debug symbols into a separate file.
(c) I guess my colleagues are forcing me to use Nuget as I can't just show up tomorrow and switch everything to Paket. I don't have to use it on my personal projects, which is nice.
Nuget's problems stem from what I'm talking about here. You need Newtonsoft.Json in various different csproj files, so you reference it in both of them. If you're not careful it easily winds up in a situation where you have multiple different versions of .NET in a single .sln file and multiple different versions of Newtonsoft.Json and the dreaded "multiple conflicting versions of a dependent assembly" warning. Etc.
Comparing it to my experience in the Java world I remember it's still possible to split the project up and open separate parts if I want, but the whole thing has one unified version of Java and a unified set of dependencies. Just never wound up with the messy tangles I see in .NET projects.
It's about my only beef with .NET stuff. Really irks me. Paket looks like a step forward though in terms of Package management, but it's not the defacto standard.
Funny thing is, I have the exact opposite problem to you. I have zero issues with packaging or Nuget in .net land. But I (along with my co workers) are regularly stuck in hell in java and scala package land. The tooling for java and scala builds is absolutely shit, whether you’re using maven or sbt. It really takes days to on board a new developer into this ecosystem just to get their build system and ide (IntelliJ) working correctly. I’ve never had to do anything like shading with nuget but we regularly have to do it in java world.
For personal projects I would never ever use java just because the amount of friction around builds and packaging is so terrible.
That seems odd. I'm particuarly fond of the fact that every Java build tool has accepted Maven's artifacts as the way to do it, whether it be sbt, Buildr, Ivy, Leinigen, Gradle etc.
I personally use Maven over sbt for Scala projects though, I much prefer declarative builds to... whatever leaky DSL sbt is rocking.
May I ask why you're routinely shading? I only really use shading for deploying Spark jobs onto a cluster I don't control. Otherwise if I'm deploying an executable jar the assembly plugin and jar-with-dependencies does it fine.
> For personal projects I would never ever use java just because the amount of friction around builds and packaging is so terrible.
As a counterpoint, I do tend to use the JVM for personal projects, but I'm also pretty strict about keeping complexity out of the build and deploy process. What that means, practically speaking, is that I compile to uberjars, and deploy as Unix services. I also have a little library that makes it easier to use an embedded in-process database for persistence.
There are surely limitations to this approach, but I don't have enough time for my side projects to get to the point where I ever hit them. So I wind up in a spot where I can generally focus on whatever the small goal of the project is.
You're quite right that by default there is no hand holding by Java itself on the matter and if you have to solve it yourself it's quite a not fun problem the first time you come across it.
It bothered me in the early days, but after switching to Spring Boot the problem melted away entirely. If you use https://start.spring.io select what you want, hit download and import as a Maven (or Gradle) project and bobs your uncle. Boot automatically builds a fat jar and it just works. Friction drops to zero in that particular configuration.
I'm not a fan of Maven either. Before leaving Java land I settled on using Gradle and was much happier with that. Some people don't like that it runs a daemon and uses resources or that builds are custom with it, but I don't mind those things at all and I found it a real breath of fresh air compared to Maven.
Another point of difference between native .NET shops and native Java shops that I have found is approach towards development environments. My sample size is small here, but so far I've seen that Java shops run windows, but have development VMs that you can just download an image, drop it into your machine, pull down the repo and the image is pre-configured with all the right stuff to build and develop. Linux natives are heavily into scripting things and the devops usually works quite nice, but I find it also breaks more frequently because it tends to be _somewhat_ brittle.
In .NET shops I haven't seen that. It's mostly been they run on Windows and develop on Windows (duh) but that means you have to manually do a bunch of setup and spend a day installing stuff when you start and everyones machine is a tiny bit different.
I can't say I've found one better than the other, but if it were me I'd run .NET Core development and do it on Linux in VMs.
(b) with a custom build step you can embed the pdb file into the assembly as embedded resource. not recommended though. the best practice I believe, is to supply a symbol package in parallel to a nuget package. _edit: there's also symbol server_
embedding debug symbols into assembly would be sometimes problematic, especially when you have public and private symbols -- signing three versions of the same assembly is not really a good idea.
(a) (c) I can feel you.. But here's what I've done to this problem:
1. use cmake for the source tree. this way you don't have trouble opening the tree as a whole.
2. in visual studio you can have both the cmake view and a solution view -- you can open a solution right from the cmake view or switch to another.
3. in this way, a solution becomes a smaller unit to organize multiple projects together. in case two projects do not have strong coupling, separate them in different solutions, and use a local nuget package source to reference.
4. of course, you'll have to roll some custom cmake script for managing nuget packages. I've done some work on this, here: https://github.com/Microsoft/GraphEngine/blob/master/cmake/F...
I've been using this approach in a few of projects at work(and also OSS ones). Insofar people are happy with it.
Both Java and C# have the same issues with conflicting dependency versions. As for conflicting .NET versions. It _would_ be the same but Java has strived (for better or worse) to stay compatible so you don't often run into that issue in Java. That has nothing to do with Maven though.
(b) Debug symbols have to be there for you to be able to have source-level debugging, of course. You can always debug the assembly code, of course. For Microsoft's tooling, PDB files are the debug symbols that link the assembly code to the source code. Other tools sometimes embed debugging information in the binaries. And if this information isn't there, you can't have source debugging either.
(c) No one's forcing you to use NuGet, although I wonder what you particular problems are with it.