What new features in java 7 is going to be implemented?
And what are they doing now?
Java SE 7 Features and Enhancements from JDK 7 Release Notes
This is the Java 7 new features summary from the OpenJDK 7 features page:
vm JSR 292: Support for dynamically-typed languages (InvokeDynamic)
Strict class-file checking
lang JSR 334: Small language enhancements (Project Coin)
core Upgrade class-loader architecture
Method to close a URLClassLoader
Concurrency and collections updates (jsr166y)
i18n Unicode 6.0
Locale enhancement
Separate user locale and user-interface locale
ionet JSR 203: More new I/O APIs for the Java platform (NIO.2)
NIO.2 filesystem provider for zip/jar archives
SCTP (Stream Control Transmission Protocol)
SDP (Sockets Direct Protocol)
Use the Windows Vista IPv6 stack
TLS 1.2
sec Elliptic-curve cryptography (ECC)
jdbc JDBC 4.1
client XRender pipeline for Java 2D
Create new platform APIs for 6u10 graphics features
Nimbus look-and-feel for Swing
Swing JLayer component
Gervill sound synthesizer [NEW]
web Update the XML stack
mgmt Enhanced MBeans [UPDATED]
Code examples for new features in Java 1.7
Try-with-resources statement
this:
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
br.close();
}
becomes:
try (BufferedReader br = new BufferedReader(new FileReader(path)) {
return br.readLine();
}
You can declare more than one resource to close:
try (
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dest))
{
// code
}
Underscores in numeric literals
int one_million = 1_000_000;
Strings in switch
String s = ...
switch(s) {
case "quux":
processQuux(s);
// fall-through
case "foo":
case "bar":
processFooOrBar(s);
break;
case "baz":
processBaz(s);
// fall-through
default:
processDefault(s);
break;
}
Binary literals
int binary = 0b1001_1001;
Improved Type Inference for Generic Instance Creation
Map<String, List<String>> anagrams = new HashMap<String, List<String>>();
becomes:
Map<String, List<String>> anagrams = new HashMap<>();
Multiple exception catching
this:
} catch (FirstException ex) {
logger.error(ex);
throw ex;
} catch (SecondException ex) {
logger.error(ex);
throw ex;
}
becomes:
} catch (FirstException | SecondException ex) {
logger.error(ex);
throw ex;
}
SafeVarargs
this:
#SuppressWarnings({"unchecked", "varargs"})
public static void printAll(List<String>... lists){
for(List<String> list : lists){
System.out.println(list);
}
}
becomes:
#SafeVarargs
public static void printAll(List<String>... lists){
for(List<String> list : lists){
System.out.println(list);
}
}
New Feature of Java Standard Edition (JSE 7)
Decorate Components with the JLayer Class:
The JLayer class is a flexible and powerful decorator for Swing components. The JLayer class in Java SE 7 is similar in spirit to the JxLayer project project at java.net. The JLayer class was initially based on the JXLayer project, but its API evolved separately.
Strings in switch Statement:
In the JDK 7 , we can use a String object in the expression of a switch statement. The Java compiler generates generally more efficient bytecode from switch statements that use String objects than from chained if-then-else statements.
Type Inference for Generic Instance:
We can replace the type arguments required to invoke the constructor of a generic class with an empty set of type parameters (<>) as long as the compiler can infer the type arguments from the context. This pair of angle brackets is informally called the diamond.
Java SE 7 supports limited type inference for generic instance creation; you can only use type inference if the parameterized type of the constructor is obvious from the context. For example, the following example does not compile:
List<String> l = new ArrayList<>();
l.add("A");
l.addAll(new ArrayList<>());
In comparison, the following example compiles:
List<? extends String> list2 = new ArrayList<>();
l.addAll(list2);
Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking:
In Java SE 7 and later, a single catch block can handle more than one type of exception. This feature can reduce code duplication. Consider the following code, which contains duplicate code in each of the catch blocks:
catch (IOException e) {
logger.log(e);
throw e;
}
catch (SQLException e) {
logger.log(e);
throw e;
}
In releases prior to Java SE 7, it is difficult to create a common method to eliminate the duplicated code because the variable e has different types.
The following example, which is valid in Java SE 7 and later, eliminates the duplicated code:
catch (IOException|SQLException e) {
logger.log(e);
throw e;
}
The catch clause specifies the types of exceptions that the block can handle, and each exception type is separated with a vertical bar (|).
The java.nio.file package
The java.nio.file package and its related package, java.nio.file.attribute, provide comprehensive support for file I/O and for accessing the file system. A zip file system provider is also available in JDK 7.
Source: http://ohmjavaclasses.blogspot.com/
Java Programming Language Enhancements # Java7
Binary Literals
Strings in switch Statement
Try with Resources (How it works) or ARM (Automatic Resource Management)
Multiple Exception Handling
Suppressed Exceptions
underscore in literals
Type Inference for Generic Instance Creation using Diamond Syntax
Improved Compiler Warnings and Errors When Using Non-Reifiable Formal Parameters with Varargs Methods
Official reference
Official reference with java8
wiki reference
In addition to what John Skeet said, here's an overview of the Java 7 project. It includes a list and description of the features.
Note: JDK 7 was released on July 28, 2011, so you should now go to the official java SE site.
Language changes:
-Project Coin (small changes)
-switch on Strings
-try-with-resources
-diamond operator
Library changes:
-new abstracted file-system API (NIO.2) (with support for virtual filesystems)
-improved concurrency libraries
-elliptic curve encryption
-more incremental upgrades
Platform changes:
-support for dynamic languages
Below is the link explaining the newly added features of JAVA 7 , the explanation is crystal clear with the possible small examples for each features :
http://radar.oreilly.com/2011/09/java7-features.html
Using Diamond(<>) operator for generic instance creation
Map<String, List<Trade>> trades = new TreeMap <> ();
Using strings in switch statements
String status= “something”;
switch(statue){
case1:
case2:
default:
}
Underscore in numeric literals
int val 12_15;
long phoneNo = 01917_999_720L;
Using single catch statement for throwing multiple exception by using “|” operator
catch(IOException | NullPointerException ex){
ex.printStackTrace();
}
No need to close() resources because Java 7 provides try-with-resources statement
try(FileOutputStream fos = new FileOutputStream("movies.txt");
DataOutputStream dos = new DataOutputStream(fos)) {
dos.writeUTF("Java 7 Block Buster");
} catch(IOException e) {
// log the exception
}
binary literals with prefix “0b” or “0B”
I think ForkJoinPool and related enhancement to Executor Framework is an important addition in Java 7.
The following list contains links to the the enhancements pages in the Java SE 7.
Swing
IO and New IO
Networking
Security
Concurrency Utilities
Rich Internet Applications (RIA)/Deployment
Requesting and Customizing Applet Decoration in Dragg able Applets
Embedding JNLP File in Applet Tag
Deploying without Codebase
Handling Applet Initialization Status with Event Handlers
Java 2D
Java XML – JAXP, JAXB, and JAX-WS
Internationalization
java.lang Package
Multithreaded Custom Class Loaders in Java SE 7
Java Programming Language
Binary Literals
Strings in switch Statements
The try-with-resources Statement
Catching Multiple Exception Types and Rethrowing Exceptions with Improved Type Checking
Underscores in Numeric Literals
Type Inference for Generic Instance Creation
Improved Compiler Warnings and Errors When Using Non-Reifiable Formal Parameters with Varargs Methods
Java Virtual Machine (JVM)
Java Virtual Machine Support for Non-Java Languages
Garbage-First Collector
Java HotSpot Virtual Machine Performance Enhancements
JDBC
Reference 1 Reference 2
Related
I have a NET 5.0 console application, from which I am trying to compile and execute external code BUT also be able to update the code, unload the previously created appdomain and re-compile everything.
This is my entire static class that handles code compilation and assembly loading
using System;
using System.IO;
using System.Collections.Generic;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using System.Reflection;
using Microsoft.CodeAnalysis.Emit;
using System.Runtime.Loader;
namespace Scripting
{
public static class ScriptCompiler
{
public static Dictionary<string, AppDomain> _appDomainDict = new();
public static object CompileScript(string scriptpath)
{
var tree = SyntaxFactory.ParseSyntaxTree(File.ReadAllText(scriptpath));
//Adding basic references
List<PortableExecutableReference> refs = new List<PortableExecutableReference>();
var assemblyPath = Path.GetDirectoryName(typeof(object).Assembly.Location);
refs.Add(MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "mscorlib.dll")));
refs.Add(MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.dll")));
refs.Add(MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Private.CoreLib.dll")));
refs.Add(MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Core.dll")));
refs.Add(MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Runtime.dll")));
// A single, immutable invocation to the compiler
// to produce a library
string hash_name = scriptpath.GetHashCode();
if (_appDomainDict.ContainsKey(hash_name))
{
AppDomain.Unload(_appDomainDict[hash_name]);
_appDomainDict.Remove(hash_name);
}
AppDomain new_domain = AppDomain.CreateDomain(hash_name);
_appDomainDict[hash_name] = new_domain;
var compilation = CSharpCompilation.Create(hash_name)
.WithOptions(
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary,
optimizationLevel: OptimizationLevel.Release,
allowUnsafe:true))
.AddReferences(refs.ToArray())
.AddSyntaxTrees(tree);
MemoryStream ms = new MemoryStream();
EmitResult compilationResult = compilation.Emit(ms);
ms.Seek(0, SeekOrigin.Begin);
if (compilationResult.Success)
{
// Load the assembly
Assembly asm = new_domain.Load(ms.ToArray());
object main_ob = asm.CreateInstance("SomeClass");
ms.Close();
return main_ob;
}
else
{
foreach (Diagnostic codeIssue in compilationResult.Diagnostics)
{
string issue = $"ID: {codeIssue.Id}, Message: {codeIssue.GetMessage()}," +
$" Location: { codeIssue.Location.GetLineSpan()}," +
$" Severity: { codeIssue.Severity}";
Callbacks.Logger.Log(typeof(NbScriptCompiler), issue, LogVerbosityLevel.WARNING);
}
return null;
}
}
}
}
Its all good when I am trying load the assembly in the current domain and execute from the instantiated object. The problem with this case is that since I wanna do frequent updates to the code, even if I make sure that the assembly names are different. I'll end up loading a ton of unused assemblies to the current domain.
This is why I've been trying to create a new domain and load the assembly there. But for some reason I get a platform not supported exception. Is this not possible to do in NET 5? Are there any workarounds or am I doing something wrong here.
Ok, it turns out that AppDomain support for NET Core + is very limited and in particular there seems to be only one appdomain
On .NET Core, the AppDomain implementation is limited by design and
does not provide isolation, unloading, or security boundaries. For
.NET Core, there is exactly one AppDomain. Isolation and unloading are
provided through AssemblyLoadContext. Security boundaries should be
provided by process boundaries and appropriate remoting techniques.
Source: https://learn.microsoft.com/en-us/dotnet/api/system.appdomain?view=net-6.0
And indeed, when trying to use AssemblyLoadContext and create object instances through these contexts everything worked like a charm!
One last note is that if the created context is not marked as collectible, its not possible to unload it. But this can be very easily set during AssemblyLoadContext construction.
I have the following method in Java 8 and I'm working in project using java 7:
public <T> List<T> getValues(CommandLineItem commandLineItemMod, Class<T> targetClass) {
Object value = values.get(commandLineItemMod);
ArrayList<T> result = new ArrayList<>();
if (value instanceof Collection) {
Collection<?> sourceCollection = (Collection<?>) value;
result.ensureCapacity(sourceCollection.size());
sourceCollection.stream().map(o -> convertValue(o, targetClass)).forEach(result::add);
} else if (value != null) {
result.add(convertValue(value, targetClass));
}
return result;
}
my question is how I can transfer the following line from java 8 to java 7 :
sourceCollection.stream().map(o -> convertValue(o, targetClass)).forEach(result::add);
thank you for your help
The line
sourceCollection.stream().
.map(o -> convertValue(o, targetClass))
.forEach(result::add);
can be rewritten as:
for (Object o: sourceCollection) {
result.add(convertValue(o, targetClass));
}
which (IMO) is a clearer way to write the code in the first place.
Having said that, public (free) support for Java 7 ended in 2015, and premium (paid) support ended in Jul7 2019. (See https://www.oracle.com/java/technologies/java-se-support-roadmap.html). So the application you are working on is on borrowed time. I would have thought it would be more sensible to port the application to a newer Java version (or phase it out entirely) rather than expending valuable developer effort on backporting Java 8 code to it.
Java 7 doesn't support Stream API. You have to use a for loop:
for(Object source : sourceCollection){
result.add(convertValue(source, targetClass));
}
For a Java / OSGi project I need to communicate with a smartcard plugged to my computer. I do this using the package javax.smartcardio.
When I first imported this package and wanted to use it, Eclipse anounced an error "Access restriction: The type 'CommandAPDU' is not API". As proposed on https://www.javacardos.com/javacardforum/viewtopic.php?t=918, I added an Accessibility Rule Pattern to the Build Path. After that, everything worked fine and I could use the package in my local environment.
But now I wanted to pass the project to our continous integration system, which is Jenkins with Maven. I also committed the .classpath file. And there I get the same error:
[ERROR] import javax.smartcardio.CommandAPDU;
[ERROR] ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[ERROR] Access restriction: The type 'CommandAPDU' is not API (restriction on classpath entry '/disc2/lunifera/server/jenkins/workspace/tools/hudson.model.JDK/JDK-8/jre/lib/rt.jar')
For some reason, the access rule does not seem to work on Jenkins. Does anybody know how to solve this problem? Thanks alot.
Not exactly the kind of answer I hoped for, but in the end, I overcame the problem by using reflection. I wrote wrapper classes for the classes from javax.smartcardio that I needed. These wrapper classes hold instances of the original classes and operate on them purely by reflection. For example, the CardTerminal class wrapper may look like this:
public class CardTerminal {
private Object originalCardTerminal;
public CardTerminal(Object originalCardTerminal)
{
this.originalCardTerminal = originalCardTerminal;
}
public Card connect(String protocol)
{
try
{
Class originalCardTerminalClass = Class.forName("javax.smartcardio.CardTerminal");
Method connectMethod = originalCardTerminalClass.getMethod("connect", String.class);
Object originalCard = connectMethod.invoke(originalCardTerminal, protocol);
if (originalCard == null)
{
return null;
}
else
{
return new Card(originalCard); // "Card" is another wrapper type, of course
}
}
catch (ClassNotFoundException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e)
{
return null;
}
}}
Of course, this is not a good solution because all the objects are just of type "object" and you lose type safety. But it's the best solution I found so far, and it's working, because you don't need to import anything from javax.smartcardio.
// given a set of Item objects, group them by the managers of creator and owners
Map<String, List<Item>> managersItems =
itemSet.parallelStream().flatMap(item -> {
// get the list of the creator and owners
List<String> users = new ArrayList();
users.add(item.getCreator());
users.addAll(item.getOwners());
return Stream.of(users.toArray(new String[] {})).map(user -> {
LdapUserInfo ldapUser = LdapUserInfoFactory.create(user);
String manager = ldapUser.getManager();
return new AbstractMap.SimpleImmutableEntry<String, Item(manager, item);
});
}).collect(
Collectors.groupingBy(Map.Entry::getKey, Collectors.mapping(Map.Entry::getValue, Collectors.toList())));
This code compiles fine in Eclipse Mars, but gets the following eror in Eclipse Luna:
Type mismatch: cannot convert from Map<Object,List<Object>> to Map<String,List<WeblabInfo>>
If I do not assign the returned to a Map with Map<String, List<Item>> managersItem = in Eclipse Luna, the error is at Map.Entry::getKey and Map.Entry::getValue statement with message:
The type Map.Entry does not define getKey(Object) that is applicable here".
What did I do wrong?
You didn't do anything wrong. Eclipse compiler has problems with type inference that causes these issues. If Luna compatibility is important, you will have to add explicit types to lambda expressions. Try, for example, Map.Entry::<String,Item>getKey
On another note, it's not necessary to convert a List to array to stream it. You can directly call users.stream(). But even creating the List isn't necessary. You can use Stream.concat(Stream.of(item.getCreator()), item.getOwners().stream()) instead (granted, it's a bit unwieldy).
Finally (and most importantly), avoid using parallelStream with blocking code, such as looking up data in an external system. Parallel streams are designed to handle CPU-bound tasks.
I was able to come up with this solution from Misha's answer. This is working with Eclipse Luna Java compiler
Map<String, List<Item>> managersItems = itemSet
.stream()
.<Map.Entry<String, Item>> flatMap(item -> {
return Stream.concat(Stream.of(item.getCreatorLogin()), item.getOwners().stream()).map(
user -> {
LdapUserInfo ldapUser = LdapUserInfoFactory.create(user);
String manager = ldapUser.getManagerLoginName();
return new AbstractMap.SimpleEntry<String, Item>(manager, info);
});
})
.collect(Collectors.groupingBy(Map.Entry<String, Item>::getKey,
Collectors.mapping(Map.Entry<String, Item>::getValue,
Collectors.toList())));
I'm upgrading a 1.0 WP7 application to CM 1.1. Among other stuff, I'm removing the old attribute-based tombstoning and implementing storage classes.
This typically involves creating a class for each VM for storage purposes, deriving it from StorageHandler<T> (where T is the type of the VM) and overriding its Configure method like e.g.:
public override void Configure()
{
Property(x => x.SomeSerializableProperty).InPhoneState().RestoreAfterViewLoad();
// ...
}
In this context, how can I implement a custom serialization mechanism using my own serialize/deserialize code for objects which could not be automatically serialized? For instance, one of my VM's has a StrokeCollection property and I'd like to serialize the strokes in it, but to this end I need to replace the default mechanism which would raise security exceptions.
Could anyone show a fake CM WP7 sample to illustrate how to customize the serialization of some property, so that I can place my own code for serializing/deserializing it?
Thanks!
I don't know if this is the right path, but it works; here is a code sample:
Property(x => x.Strokes).InPhoneState().RestoreAfterViewReady().Configure(x =>
{
x.Save = SaveStrokes;
x.Restore = RestoreStrokes;
});
with their implementations like:
void SaveStrokes(BoardViewModel vm, Func<string> serialize, StorageMode nMode)
{
IsolatedStorageSettings.ApplicationSettings[vm.DisplayName + "ThePropertyKey"] =
// ...get data from vm and serialize
}
and conversely:
void RestoreStrokes(BoardViewModel vm, Func<string> serialize, StorageMode nMode)
{
// use IsolatedStorageSettings.ApplicationSettings[vm.DisplayName + "ThePropertyKey"]
// to check if the key exists, and if it is there get the serialized data and deserialize
}
As for strokes, I'm using my own serialization class as my usual tool for this purpose (SharpSerializer) seems having issues in restoring (it throws an ambiguous match reflection exception).