What controls the version of a java application? [closed] - java

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
By "controls" I suppose I mean a couple of things.
Basically I struggled a bit early on in the java application for my Case Study working with Eclipse to configure everything properly get it to be error free and then run, and finally I got it working through some POM settings and maven>updating project and didn't have any more issues. Then I downloaded our whole cohort's case studies and I got a lot of similar errors (red Xs in Eclipse) in most of the projects, and it seems like if I go through them one by one and configure version, among other things, they work.
So my understanding of Java/Eclipse errors and their relation to Maven and JRE version is kind of fuzzy but this is my working model (which may be wrong in some parts):
Each version of Java adds new features (obviously), and Java 1.8 was a major milestone but for the most part, for most of these projects, it seems you can pick and choose whatever version you like, as long as you configure your project settings properly. It's dealer's choice basically (?). If you compile in the command line, these things may not apply or may be passed as args.
But to configure your project properly, I guess you can go into build path and do it that way (?), but the preferred way is to have maven handle the dependencies, including the core Java Runtime library dependency (the language version itself) and you do that by setting a property in the pom.xml (which may or may not be present. Which is optional but I think recommended). Then (when you maven>"update project"), it syncs and overwrites what is the default, and it it is the system or IDE default that is causing the intial conflict. (?). Do I understand this correctly?
And maven/Eclipse knows to respect maven more than the build path or it replaces the build path, because it understands that it wants an all-in-one source of configuration truth?
And having the wrong version of java specified, even if it's closely related versions like 11 and 13, can make it seem like you have tons of errors in your code. It can't even find the common classes like String, because they are technically different, because that's just the way Java configured it, unlike perhaps other languages.
When you import a project into your IDE (e.g. Eclipse), you are given by Eclipse a default JRE version based on your IDE settings or what you downloaded, or something, but the project may expect a different version (why or wherefore, I am not sure but this seems to be the case and what throws errors or makes Eclipse throw errors). Yet if I update the maven project by right clicking, it doesn't necessarily fix the issues. My understanding is because the pom file is not complete enough, with missing properties that should ideally be there, for this very reason: e.g. source, target and release
I had a project that threw erorrs that seemed to go away when I changed
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<release>15</release>
</configuration>
</plugin>
To
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<release>11</release>
</configuration>
</plugin>
Adding the source and target and changing release to 11.
It might have worked at 15 but I don't remember downloading 15 ever, and I'm not sure it had to be on my system or if maven downloads it.
Maybe Eclipse was screaming that the source did not match the release, because I didn't have 15 on my system. My case study had 11, so that's why I chose that even though I think I have 14 on my system. There's too many moving pieces, but that's what I want to figure out once and for all- what is going on.
Target and release seem like the same concept, so maybe they are duplicates. Maybe they are instructing the compiler or IDE to the same end. It doesn't seem like the source should have to match the target or they wouldn't give us the option.
I'm trying to figure why I had errors.
What gets me is it seems that the imported projects know enough to know the Eclipse Java version is wrong, but it doesn't know enough to update to the correct when I updated the maven projects. We were employee-students in a nice long paid training so we couldn't be expected to know everything but would this be due to the fact that the pom.xml config files that are part of the projects are sub-optimal and incomplete in themselves that require additional config that I had to do, or are they fine and the problem was on my end? What seems funny is the system seems to know enough to know things are wrong (wrong version) but not enough to know how to make it right (or at least not given the command).
But if I choose a random suitable version (11) and I put that in a few properties in pom, (target, release) and update, then it seems to work. It overwrites the Eclipse default, the prior pom project default, if any, wherever that is coming from or being inferred from, and my new (pseudo random) version becomes the source of truth and it is happy, not that it needed a particular version, but that it just needed someone to state a fixed version plainly. In that sense, nothing 'controls' which version has to be used. You just have to assert it in the right place, as long as your basic code features are supported (and they probably are).
I don't know if I understand this right. There are many moving parts that I'm always wrestling with. I thought this would be a good learning opportunity to figure this aspect of the language out or make progress. I think Eclipse and maven are doing a lot of things implicitly that I'm not aware of, that I need to be, or there are settings I don't fully understand that are being read, and you can't know what needs to be just by using logic, because of implicitness, and also Java is funny and more strict with its language versions, in that a String in v 11 is not the same class as a String in v 12, if I understand right.
Knowing how my mind works, liking to deconstruct the moving pieces and see how it works and fits under the hood mechanically, if anyone has any good reading material on the topic, I'd appreciate that too. I love coding. I don't necessarily love configuring, especially when I don't know what I'm configuring and why.

Note the following:
There is a difference between the installed JDK and the target Java version. The installed JDK needs be at least as high as the target Java version.
The only relevant Java versions at the moment are 8, 11 and 16. All others are obsolete and should not be used.
Fundamental classes as "String" do not change from one version to the other, but Eclipse tends to show strange errors.
The truth is always on the command line. If you want to find the real errors, run mvn clean verify. Errors in Eclipse may be misleading or just rubbish.

Related

Can builds from the same source code yield functionally different executables?

Recently, a colleague of mine said something along these lines: "consecutive APKs (executables) produced by build server from the same source code might not be the same". The context for this discussion was whether QA performed on build X also applies to build Y, which was performed by the same build server (configured the same way) from the same source code.
I think that generated executables might not be identical due to various factors (e.g. different timestamp), but the question is whether they can be functionally different.
The only scenario, that I can think of, in which the same source code could produce different functionality is that of multi-threading issue: in case of incorrect synchronization of multi-threaded code, different re-ordering/optimization actions performed at compile time could affect this poorly synchronized code and change its functional behavior.
My questions are:
Is it true that consecutive builds performed by the same build server from the same source code can be functionally different?
If #1 is true, are these differences limited to incorrectly synchronized multi-threaded code?
If #2 is false, what are the other parts that can change?
Links to any related material will be appreciated.
It's certainly possible in a few cases. I'll assume you are using Gradle to build your Android app.
Case 1: You are using a 3rd party dependency that's included with a version wildcard, such as:
compile somelib.1+
It's possible for the dependency to change in this case, which is why it's highly recommended to use explicit dependency versions.
Case 2: You're injecting environment information into your app using Gradle's buildConfigFields. These values will be injected into your app's BuildConfig class. Depending on how you use those values, the app behavior could vary on consecutive builds.
Case 3: You update the JDK on your CI in-between consecutive builds. It's possible, though I'd assume highly unlikely, that your app behavior could change depending on how it's compiled. For example, you might be hitting an edge case in the JDK that gets fixed in a later version, causing code that previously worked before to act differently.
I think this answers your first question and second question.
edit: sorry, I think I missed some important info from your OP. My case 2 is an example of your e.g. different timestamp and case 3 violates your configured the same way. I'll leave the answer here though.
I think that different functionality may be caused only by discrepancies in environment or maybe you are using snapshot version of some 3rd party library, and thus it was updated after some time.
some advice:
if it possible to rebuild it, use verbose mode of build tool (-X in maven for example) and compare output line by line with some diff program
If the same source code could produce different results on the same machine / configuration, programming as we know it would probably not be possible.
There is always an option that things break, when the language level, operating system, or some other dependency changes. If all that changes it the time of the build, you would have to do something fundamentally wrong.
Using android / gradle, one possible reason to lead to a different behavior or errors in general is using + in your build.gradle file for library versions. This is why you should avoid doing so, since a consecutive build could fetch a newer / different version, hence you'd have different source code, and thus it could create a functional different executable.
A good build should always be repeatable. This means given the same configuration it should have the same results. If it isn't, you could never rely on anything and would have to do total regression testing on everything.
[...] consecutive builds performed by the same build server from the same source code can be functionally different
No. As described above, if you use the same versions, the same source code, it should produce the same behavior. Unless you do something very wrong.
[...] are these differences limited to incorrectly synchronized multi-threaded code?
This would imply a bug with your compiler. While this is possible, it is extremely unlikely.
[...] what are the other parts that can change?
Besides the timestamp and the build number nothing else should change, given the same source code and configuration.
It is always a good idea to include unit (and other) tests in your build. This way you can test specific behavior to be the same with each build.
They should be identical,except:
there is threading/optimization issues in build system.
hardware failures CPU/RAM/HDD issues on build environment
time/platform related code in build system itself or build scripts
So if you are building exact same code on exact same HW using exact same version of build system, same OS version and your code DO NOT SPECIALLY DEPEND from build time result should be same. They even should have exact same check sums and size.
Also results is same ONLY if your code do not depend on external modules which is downloaded from Internet at build time like Gradle/Maven does - you can't grantee this libraries the same because of they are not in version control. Moreover there is can be dependency where module version specified not exactly (like 2.0.+) so if maintainer updated this module your build system will use updated one -> so basically your builds generated from different source code.
As somebody mention using Unit tests on build server is good practice to make sure your build is stable and don't contain obvious bugs.
While this question addresses Java/Android, Jon Skeet blogged about different C# parsers treating some Unicode characters differently, mostly due to changes in the Unicode character database.
In his examples, the Mongolian Vowel Separator (U+180E) is considered either a whitespace character or a character allowed within an identifier, yielding different results in variable assignments.
It is definately possible. You can construct an example program that will behave different in functionality everytime you start it up.
Imagine a strategy design pattern that lets you choose between algorithms during runtime and you load one algorithm based on RNG.

Why use project clean in eclipse?

I've been working as a Java developer for just short of a year now and am gradually trying to increase my knowledge to speed up development times. One of the habits I find myself doing is forcing an occasional clean without really knowing if I need it.
I get that if you use it, your project will be completely re-built, however I don't fully understand under what circumstances I would want to use it.
If I understand correctly, most, if not all, changes to a project will be built automatically, so with that there should only be a rare occasion that I would actually need to use a project clean.
Clean is useful if some external tool modifies your output folder. For example, you are using Eclipse, but occasinally compile via command line compiler into the same folder. In this case Eclipse may fail to do incremental build and display errors in code when they are actually absent.
Another case is working around some bug in Eclipse compiler itself. In very rare cases and in specific Eclipse versions/updates some classes which are necessary to be recompiled after specific code changes might be overlooked by compiler. If you were (un)happy enough to encounter such case, clean will help you.
It is for example useful if you delete a class, and then you forget to remove a reference to it in another class. If you do not clean the project, your local copy will still work, but what you actually did is that you just broke the build. ;)
Your local copy of the project will still work because the .class of the deleted class will still be there. To find out problems like this, is usually a good thing to compile the project from scratch on the integration system.

Possible usage of an automated compiler error fixing plugin

I am working on a project aims to make software reuse easier. The final project provides a framework to select a desired feature from a (Java, C++) program and adds that to the another program.
I am responsible for two parts of the project.
Fixing possible compiler errors after the desired feature is added to the another program.
Changing the desired feature to be usable in its new location. In this case the program should pass successfully all test cases (not details at the moment as my question is related to Section 1).
Currently, I implemented the first step and the program can automatically fix possible compiler errors after the desired feature is added to its new location. It almost supports all Java compiler errors (even that some of them never happen in the above project), and in few of cases a user needs to help the plugin to fix the compiler error.
Note that the plugin has access to both programs and using these information it will fix compiler errors.
For clarity, as a very simple example in a case that there is a dependency between the desired feature with a library in its original location, the plugin tries to fix the compiler error for example by adding that library to the program.
I know current IDEs provide suggestions in a case that there is a compiler error in the program, but the advantage of the current plugin is that it automatically can fix compiler errors, and does not provide a list of solutions to the user for each compiler error.
The question That I am facing is that: Any one could please mention other situations that I can use the implemented automated compiler error fixing plugin? (of course except the above project). Any suggestion is welcome as it helps me to see other directions of the project.

Eclipse errors on startup

Sorry if this question is kind of vague. Let me know if I can provide any additional relevant details.
Basically, every so often (at least once every few weeks), when I open my Eclipse workspace I am greeted with a large number of errors. It often says that almost every single one of my projects have errors even though they were working just the day before. I understand that something is getting messed up in the build-path because it gives me errors such as The type java.lang.Object cannot be resolved. However, I don't understand why restarting Eclipse would cause this build-path to get messed up. It also seems fairly common for me to get errors on imports for various Android classes even though I have included the Android SDK in the project.
I guess what I am asking is twofold:
1) Why is this happening and is there anything that I can do to stop this from happening?
2) When this does happen, is there an easy way that I can resolve it? I know that I can go into the Preferences for an individual project and add libraries to the build-path but I can't figure out how to easily do this for all of my projects at once, and I feel like I'm just trying things until they work, so it would be good to have a more defined procedure for dealing with these sorts of problems.
EDIT:
Does anyone have any ideas?
You might need a valid JRE or JDK defined in the Java Build Path of your project.

Best ways to manage generated artifacts for web service/xml bindings in a java webapp/client?

I'm working on a couple of web services that use JAXB bindings for the messages (in JAX-WS or spring-ws). When using these bindings there's always some code that is automatically generated from the WSDL to bind the message objects. I'm struggling to figure out the best way I can make this work so that it's easy to work with, hard to break and integrates nicely with IDEs (mostly using eclipse).
I think there are a couple of ways to go about this. The three main options I see right now are:
Generate code, keep the source artifacts and check them into the repository. Pros: integrates easily with IDEs (source highlighting etc), works within the build system. Cons: generated code changes each time you regenerate it, possibly creating noisy commits. It's also redundant since the WSDL file is already checked in, usually.
Generate code as part of the build process. Don't keep source artifacts or only keep them in output directories. Pros: fixes all the cons from the previous one. Cons: harder to integrate with IDE, though maybe this build step can be run automatically? I currently use this on one of my projects but the first time I checkout the project it appears broken, which is a minor nuisance.
Keep generated bindings in separate libraries (jars) included with maven or manually updated jars, depending on your build process. I got the idea from a thread on java.net. This seems more stable and uses explicit versioning but seems a bit heavyweight.
Which one of these options would you implement and how? We're currently using maven and eclipse, so any ideas in that regard would be great. I think this problem generalises to most other build systems and IDE combinations though, even other languages perhaps.
I went for option 3. If you already host your own repository (and optionally CI), it's not that heavyweight. All it takes is a simple POM. It's even possible to include some utility/wrapper/builder classes (that often make life easier with generated classes) and use them in several projects.
I'd go for option 2 and generate code in the "standard" ${project.build.directory}/generated-sources/<toolname> location as part of the build process. Using generated sources is well supported by m2eclipse (use Maven > Update Project Configuration once sources have been generated) and, if I remember well, by the maven eclipse plugin as well (i.e. the folder will be added to the Java Build Path). Actually, I think NetBeans also handle this fine. Not sure for Idea.
For the generation itself, you may need the maven-jaxb2-plugin if I understood correctly.

Categories