Hot answers tagged

102

Shading dependencies is the process of including and renaming dependencies (thus relocating the classes & rewriting affected bytecode & resources) to create a private copy that you bundle alongside your own code. The concept is usually associated with uber-jars (aka fat jars). There is some confusion about the term, because of maven shade plugin, ...


86

Not at all. Imagine you're running the version 1.8.0 of Java on both your development machine and the server. By the way, you're working simultaneously on two projects, both using Java. One day, a bug is found in JVM, and the servers which run the first project you're working on are migrated to 1.8.1. By the way, the servers running the second project aren'...


79

The logic is that JVM bytecode is a lot simpler than Java source code. Compilers can be thought of, at a highly abstract level, as having three basic parts: parsing, semantic analysis, and code generation. Parsing consists of reading the code and turning it into a tree representation inside the compiler's memory. Semantic analysis is the part where it ...


44

As a general rule, if it were absolutely never, ever acceptable to do something, and there was agreement about that, the language implementers would not have allowed it. There are almost no such unanimously clear-cut maxims. (Luckily, because that's what keeps us human programmers in jobs!) It looks very much as if you've found a situation where catching ...


37

Compared to other VMs, the JVM actually isn't particularly versatile. It directly supports statically typed OO. For everything else, you have to see what parts you can use, and how you can build everything else your language needs on top of those parts. For example, until Java 7 introduced the invokedynamic bytecode, it was very hard to implement a ...


35

You rarely just deploy a "Java App". Your java application has a lot of different support programs around it. We use Apache HTTPD, Apache Tomcat, ActiveMQ for messaging, an FTP Deamon, MySQL and a handful of custom services to integrate with programs that don't work directly with Java. This doesn't even go into the development software that goes along ...


32

"All" programming languages run on x86, so how can they be much different from each other? Brainfuck and Haskell are both Turing complete, so they can both do the exact same tasks. There's a bit of room for syntax changes, syntax sugar and compiler magic in between. You can do quite a lot in there, but there is always a limit. In your case, it's JVM byte ...


27

Intermediate representations of various sorts are increasingly common in compiler / runtime design, for a few reasons. In Java's case, the number one reason initially was probably portability: Java was heavily marketed initially as "Write Once, Run Anywhere". While you can achieve this by distributing the source code and using different compilers to target ...


24

To address the specific issue that you raise, of reified generics . . . In many contexts, type parameters are actually saved in class-files and exploitable via reflection, even despite erasure. For example, the following program prints class java.lang.String: import java.lang.reflect.Field; import java.lang.reflect.ParameterizedType; import java.util....


23

The key is the native language of the JVM: the Java bytecode. Any language can be compiled into bytecode which the JVM understands - all you need for this is a compiler emitting bytecode. From then on, there is no difference from the JVM's point of view. So much so that you can take a compiled Scala, Clojure, Jython etc. class file and decompile it (using e....


21

In this video I watched recently, Rich Hickey comments that he likes the destructuring part of languages like Scala, but not so much the pattern matching part, and he designed Clojure accordingly. That probably explains why the pattern matching is in a library and not as robust, although the kind of problems seen in the post you mentioned are clearly bugs. ...


19

You might think that the public static void main method in Java or the main function in C is the real entry point of your program – but it isn't. All high-level languages (including C) have a language runtime that initializes the program, and then transfers control flow to the entry point. In the case of Java, initialization will include: setting up the JVM ...


18

C is what I would call a mid-level language. Its purpose is to serve as a "very high-level assembler," which is why it works so well as a compiler target, and why it embraces portability so well. Historically, interpreters have typically been used with high-level languages, in the context of method calls. In its simplest form, an interpreter merely parses ...


13

I did a bit of this when I started with Java, years ago. My approach was to read the VM spec, and to look at the output of javap -c, which displays the disassembled bytecode of a class. I also tried creating java classes with particular bytecode, using a java bytecode assembler. There is an assembler called jasmin, if you want to try that. You might also ...


13

The code for methods is part of the Class (more concisely, Class<Student>) and it is loaded into memory when the class is first loaded. That said, when you execute any method additional memory is used, to allocate memory to parameters, local variables, temporary expression results, return values and so on. But such memory is allocated in the stack (...


13

Java is portable in the sense that C or C++ can be portable: the same source code can be used for multiple operating systems or processor architectures. In fact this is a lot easier in Java, since the JVM abstracts over many platform-specific details (such as the size of a long int, or endianness), and the standard library abstracts over the functionality ...


12

Clojure could perform automatic optimisation of tail recursion into loops: it is certainly possible to do this on the JVM as Scala proves. It was actually a design decision not to do this - you have to explicitly use the recur special form if you want this feature. See the mail thread Re: Why no tail call optimization on the Clojure google group. On the ...


12

For the visually minded, here's a parable by Kieron Briggs: Picture a big empty room with a big furnace/incinerator type thing at one end. Hanging form the roof are a number of ropes, called Threads. Attached to the various threads are little sparkly Objects, and those Objects can have other Object attached to them in turn by little rods called References....


10

Since native compilers for Java, C# etc. exist, it is obviously possible. Whether or not a language is "managed" is a question of language semantics, not the implementation. It doesn't matter whether it's a compiler, an interpreter or a mixed-mode implementation. Every language can be implemented with a compiler and every language can be implemented with an ...


10

There are two major differences between the two. First: the JVM is abstract, PyPy is concrete. The JVM is a specification, a piece of paper. PyPy is an implementation, a piece of code. There are many different implementations of the JVM which work very differently. Some only interpret the JVM byte code, some only compile it statically ahead-of-time, some ...


10

While the other answers are giving good information about the internal details of certain various JVM heap designs, from the programmer's perspective, there is only one heap and one way to use it -- via new for allocation and via letting go for deallocation. Thus, I would say that there is no availability of different kinds or areas of a Java heap for ...


9

One of the most important aspects of the .NET virtual machine is the reason why it is called the Common Language Runtime. All .NET programming languages compile to the same bytecode format which is executed in the same VM. This allows programs where different parts are written in different programming languages to interoperate seamlessly. Virtual machines ...


9

A processor executes machine instructions. They are the only thing that a processor understands. Java bytecode is an intermediate, compact, way of representing a series of operations (for want of a better term). The processor can't execute these directly. The Java Virtual Machine processes that stream of bytecode operations and interprets them into a ...


8

I think the main reason is simply that the demand for this feature is not very high, because upgrading to newer JVMs is generally quite painless. And the kind of organizations and people who insist on running outdated JVMs anyway are probably not keen on using the newest language features either. Of course, it's certainly possible - nobody prevents you from ...


8

1) specify a grammar for your language 2) write or generate code that parses to that grammar 3) build an abstract syntax tree 4) perform optimisations (optional) 5) compile to JVM bytecode. The JVM spec is here


8

How about a benchmarking suite? Rather than letting the GC run at any random time, you might want to make it run between sets of tests, to (possibly) create more consistent conditions for each set.


Only top voted, non community-wiki answers of a minimum length are eligible