I've been a Java developer for many years developing mostly MVC Web applications using Spring. I am learning Kotlin and Android as a self development project, and mostly love it. I normally just figure things out, but I think I am missing something big here (as I like writing code that is easy to maintain and not prone to Exceptions). I understand the inter-operability with Java, I'm just confused on how my Kotlin code compiles and gives me no sort of warning whatsoever that a Java method call throws an Exception.
Here is a very simple example I have from the Android Tutorials on how to write a file that demonstrates this issue (From Camera Intent Tutorial). File.createTempFile() throws IO Exception in Java but Kotlin allows me to just call this method as if nothing throws any exceptions at all. If I remove the #Throws annotation on the method I get no warning that I'm calling a method that has the potential to throw an Exception.
#Throws(IOException::class)
private fun createImageFile(): File {
// Create an image file name
val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
val storageDir: File = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
return File.createTempFile(
"JPEG_${timeStamp}_", /* prefix */
".jpg", /* suffix */
storageDir /* directory */
).apply {
// Save a file: path for use with ACTION_VIEW intents
currentPhotoPath = absolutePath
}
}
I'm just confused on how I am supposed to keep track of Java methods that throw Exceptions. I know a lot of Exceptions and this example has the Exception in it, but by no means do I know (or could I know) every Exception possible for every method call in Java and/or Java libraries. Am I supposed to go look at the source code of every method I call to make sure I am not missing an Exception? That seems very tedious and quite a bit of overhead on a large scale codebase.
This is called perfectly fine from my code without the #Throws annotation even though it throws IO Exception in Java. How am I supposed to know if a Java method is throwing an Exception I need to take into account while coding (without looking at the source code)?
private fun createImageFile(): File {
// Create an image file name
val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
val storageDir: File = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
return File.createTempFile(
"JPEG_${timeStamp}_", /* prefix */
".jpg", /* suffix */
storageDir /* directory */
).apply {
// Save a file: path for use with ACTION_VIEW intents
currentPhotoPath = absolutePath
}
}
I have read the documents on Exceptions and on Java inter-operability, I am just wondering if there is an easier way to tell if a Java method throws an Exception then looking at the source code (maybe I missed something)?
https://kotlinlang.org/docs/reference/java-interop.html
https://kotlinlang.org/docs/reference/exceptions.html
//Checked Exceptions
//In Kotlin, all exceptions are unchecked, meaning that the compiler does not force you to catch any
//of
// them. So, when you call a Java method that declares a checked exception, Kotlin does not force you
//to
//do anything:
fun render(list: List<*>, to: Appendable) {
for (item in list) {
to.append(item.toString()) // Java would require us to catch IOException here
}
}
I suggest you check with Intellij. If I use a method throwing an exception in my code, It hints me. It also suggests me to include throws Exception my method definition
Consider there are 3 methods,
A()throws Exception;
B(); //which calls A inside
C();// which calls B inside
This code will compile in Java without complaining. But it's not the best practice, throw Exception is much important like return type in the method definition. Especially in multi-developer projects. It improves usability and documentation.
Am I supposed to go look at the source code of every method I call to make sure I am not missing an Exception?
While using external libs, you don't need to know about the source code but you must refer the documentation to know about its behaviours.
what's the purpose of the method.
Whether it throws Exception or not. If so, Should I handle it or not.
The return type, which you obviously know.
I am working in a repository maintained by 200 developers. And we also practice the above.
And in addition, Java reflection has the library Method.getExceptionTypes() which will list you all the exceptions throwing by a method in runtime.
Note: I am Java developer and don't know much about Kotlin grammars
Since Kotlin doesn't support checked exceptions, you're out of luck when using a Java library. You just have to be diligent about looking at the docs of methods you're calling.
If you're writing a Kotlin library, you can box your result in a class that wraps a successful result or an error. Or you can use sealed classes. For example:
sealed class QueryResult
class Success(val result: List<String>): QueryResult()
class IncorrectSyntaxError(val msg: String): QueryResult()
class ConnectionError(val msg: String): QueryResult()
And then your function can return one of the above subclasses. The receiver can then use a when statement to handle the result:
var result: List<String>? = null
val query = doQuery()
when (query ) {
is Success -> result = query.result
is IncorrectSyntaxError -> showErrorMessage(query.msg)
is ConnectionError -> showErrorMessage(query.msg)
}
I need to show on my panel the working dir.
I use String value = System.getProperty("user.dir"). Afterwards i put this string on label but I receive this message on console:
The method getProperty(String, String) in the type System is not applicable for the arguments (String).
I use eclipse.
Issue
I am guessing you have not gone through GWT 101 - You cannot blindly use JAVA CODE on client side.
Explanation
You can find the list of classes and methods supported for GWT from JAVA.
https://developers.google.com/web-toolkit/doc/latest/RefJreEmulation
For System only the following are supported.
err, out,
System(),
arraycopy(Object, int, Object, int, int),
currentTimeMillis(),
gc(),
identityHashCode(Object),
setErr(PrintStream),
setOut(PrintStream)
Solution
In your case Execute System.getProperty("user.dir") in your server side code and access it using RPC or any other server side gwt communication technique.
System.getProperty("key") is not supported,
but System.getProperty("key", "default") IS supported, though it will only return the default value as there is not system properties per se.
If you need the working directory during gwt compile, you need to use a custom linker or generator, grab the system property at build time, and emit it as a public resource file.
For linkers, you have to export an external file that gwt can download and get the compile-time data you want. For generators, you just inject the string you want into compiled source.
Here's a slideshow on linkers that is actually very interesting.
http://dl.google.com/googleio/2010/gwt-gwt-linkers.pdf
If you don't want to use a linker and an extra http request, you can use a generator as well, which is likely much easier (and faster):
interface BuildData {
String workingDirectory();
}
BuildData data = GWT.create(BuildData.class);
data.workingDirectory();
Then, you need to make a generator:
public class BuildDataGenerator extends IncrementalGenerator {
#Override
public RebindResult generateIncrementally(TreeLogger logger,
GeneratorContext context, String typeName){
//generator boilerplate
PrintWriter printWriter = context.tryCreate(logger, "com.foo", "BuildDataImpl");
if (printWriter == null){
logger.log(Type.TRACE, "Already generated");
return new RebindResult(RebindMode.USE_PARTIAL_CACHED,"com.foo.BuildDataImpl");
}
SourceFileComposerFactory composer =
new SourceFileComposerFactory("com.foo", "BuildDataImpl");
//must implement interface we are generating to avoid class cast exception
composer.addImplementedInterface("com.foo.BuildData");
SourceWriter sw = composer.createSourceWriter(printWriter);
//write the generated class; the class definition is done for you
sw.println("public String workingDirectory(){");
sw.println("return \""+System.getProperty("user.dir")+"\";");
sw.println("}");
return new RebindResult(RebindMode.USE_ALL_NEW_WITH_NO_CACHING
,"com.foo.BuildDataImpl");
}
}
Finally, you need to tell gwt to use your generator on your interface:
<generate-with class="dev.com.foo.BuildDataGenerator">
<when-type-assignable class="com.foo.BuildData" />
</generate-with>
I need to refactor code in a wide term. I know that from inside the Eclipse IDE I can refactor my classes. But is there any API that I can use in a java project so that I can refactor projects dynamically through code?
I need some idea on how to achieve the following: a program that calls all the Eclipse refactorings for renaming and moving in a loop to refactoring the entire project in one shot!
I don't want to introduce new refactoring types by extending the refactoring classes. I just want to call them programmatically.
Something like this?
Anyone who supports a programming language in an Eclipse-based IDE
will be asked sooner or later to offer automated refactorings -
similar to what is provided by the Java Development Tools (JDT). Since
the release of Eclipse 3.1, at least part of this task (which is by no
means simple) is supported by a language neutral API: the Language
Toolkit (LTK). But how is this API used?
EDIT:
If you want to programmatically run refactorings without using the UI, RefactoringDescriptors (see article) can be used to fill in the parameters and execute the refactoring programmatically. If you create a plugin that depends on org.eclipse.core.runtime and add the org.eclipse.core.runtime.applications extension, you will be able to run an IApplication class from eclipse similar to a main(String[]) class in plain java apps. An example of calling the API can be found on the post.
ICompilationUnit cu = ... // an ICompilationUnit to rename
RefactoringContribution contribution =
RefactoringCore.getRefactoringContribution(IJavaRefactorings .RENAME_COMPILATION_UNIT);
RenameJavaElementDescriptor descriptor =
(RenameJavaElementDescriptor) contribution.createDescriptor();
descriptor.setProject(cu.getResource().getProject().getName( ));
descriptor.setNewName("NewClass"); // new name for a Class
descriptor.setJavaElement(cu);
RefactoringStatus status = new RefactoringStatus();
try {
Refactoring refactoring = descriptor.createRefactoring(status);
IProgressMonitor monitor = new NullProgressMonitor();
refactoring.checkInitialConditions(monitor);
refactoring.checkFinalConditions(monitor);
Change change = refactoring.createChange(monitor);
change.perform(monitor);
} catch (CoreException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
If you have more detailed questions about using the JDT APIs (AST, Refactoring, etc) I'd suggest you ask on the JDT Forum.
The answer below is great, but I answered with a wider perspective for the people who need a more bulky and tasty crunch of this wonderful cake:
RefactoringStatus status = new RefactoringStatus();
IWorkspace workspace = ResourcesPlugin.getWorkspace();
IWorkspaceRoot root = workspace.getRoot();
IProject[] projects = root.getProjects();
then:
for (ICompilationUnit unit : mypackage.getCompilationUnits()) {
IType primary = unit.findPrimaryType();
IMethod[] methods = primary.getMethods();
int i = 1;
for (IMethod method : methods) {
if (method.isConstructor()) {
continue;
}
makeChangetoMethods(status, method,"changedMethodVersion_" + i);
++i;
}
}
After that:
IProgressMonitor monitor = new NullProgressMonitor();
status = new RefactoringStatus();
Refactoring refactoring = performMethodsRefactoring(status, methodToRename, newName);
then:
Change change = refactoring.createChange(monitor);
change.perform(monitor);
find below the code for setting the descriptor:
String id = IJavaRefactorings.RENAME_METHOD;
RefactoringContribution contrib = RefactoringCore.getRefactoringContribution(id);
RenameJavaElementDescriptor desc = contrib.createDescriptor();
desc.setUpdateReferences(true);
desc.setJavaElement(methodToRename);
desc.setNewName(newName);
desc.createRefactoring(status);
I am coding in GWT 2.3 using Eclipse. While I have had coding experience, it has been limited to client-side. My current project involves creating a mapping program, which takes a list of points from an Excel sheet and places them on a predefined image. Now, I have my servlet and my client code connected, and I already have some idea how to read the Excel file.
My current problem: I get the following error when I load my application on Firefox using Development Mode:
Something other than an int was returned from JSNI method '#com.google.gwt.user.client.rpc.impl.ClientSerializationStreamReader::readInt()': JS value of type undefined, expected int
Development Mode's console doesn't give me any errors when I run, those it does tell me there is a [WARN] with two things I'm not using (images which I misnamed, but do not load ever).
Currently, my code is as follows:
In my Floor.java client side code:
MyServiceAsync service = (MyServiceAsync) GWT.create(MyService.class);
AsyncCallback<String> callback = new AsyncCallback<String>() {
public void onFailure(Throwable caught) {
printerModel.setText("FAILED");
String details = caught.getMessage();
printerModel.setText(details);
}
#Override
public void onSuccess(String result) {
//I purposefully have this as an empty method so I could figure out the error
}
};
service.readFile("PrinterList.xls", callback);
In my MyService.java:
>public String readFile(String s);
In `MyServiceImpl.java`:
>public String readFile(String s) {
// TODO Auto-generated method stub
try {
} catch (Exception e) {
}
return "foo";
}
My AsyncCallback type is String, which seems to be causing the error. The method my client code calls returns a single String at this point, "fubar" (for simplicity). I thought that Strings were automatically serializable, but I am not sure. So, how do I get this error to go away? And how do I make the server code serialized?
What the exception says is basically this:
Client was trying to read an object from the data stream. Based on the signature of called method (or some other hint) the stream reader was expecting an int but found undefined instead.
As for the serializability of String, your assumption is correct. They are serializable without any effort on your part.
Without looking at the code and/or exception trace, it's difficult to say anything more.
EDIT:
Your code seems fine to me. Is there a chance that you are mixing GWT versions? That is you compiled your GWT application with 2.3, but the server classpath contains an older GWT jar (or vice versa). Take a look at:
Project GWT version settings. Project-> Properties -> Google -> Web Toolkit. Which version of GWT is selected there?
Compare the GWT settings with Project -> Properties -> Java Build Path -> Libraries. How many GWT related jars do you see there? Which version? Are there more than one gwt-servlet-x.y.jar?
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 7 years ago.
Improve this question
I'm looking for a framework to generate Java source files.
Something like the following API:
X clazz = Something.createClass("package name", "class name");
clazz.addSuperInterface("interface name");
clazz.addMethod("method name", returnType, argumentTypes, ...);
File targetDir = ...;
clazz.generate(targetDir);
Then, a java source file should be found in a sub-directory of the target directory.
Does anyone know such a framework?
EDIT:
I really need the source files.
I also would like to fill out the code of the methods.
I'm looking for a high-level abstraction, not direct bytecode manipulation/generation.
I also need the "structure of the class" in a tree of objects.
The problem domain is general: to generate a large amount of very different classes, without a "common structure".
SOLUTIONS
I have posted 2 answers based in your answers... with CodeModel and with Eclipse JDT.
I have used CodeModel in my solution, :-)
Sun provides an API called CodeModel for generating Java source files using an API. It's not the easiest thing to get information on, but it's there and it works extremely well.
The easiest way to get hold of it is as part of the JAXB 2 RI - the XJC schema-to-java generator uses CodeModel to generate its java source, and it's part of the XJC jars. You can use it just for the CodeModel.
Grab it from http://codemodel.java.net/
Solution found with CodeModel
Thanks, skaffman.
For example, with this code:
JCodeModel cm = new JCodeModel();
JDefinedClass dc = cm._class("foo.Bar");
JMethod m = dc.method(0, int.class, "foo");
m.body()._return(JExpr.lit(5));
File file = new File("./target/classes");
file.mkdirs();
cm.build(file);
I can get this output:
package foo;
public class Bar {
int foo() {
return 5;
}
}
Solution found with Eclipse JDT's AST
Thanks, Giles.
For example, with this code:
AST ast = AST.newAST(AST.JLS3);
CompilationUnit cu = ast.newCompilationUnit();
PackageDeclaration p1 = ast.newPackageDeclaration();
p1.setName(ast.newSimpleName("foo"));
cu.setPackage(p1);
ImportDeclaration id = ast.newImportDeclaration();
id.setName(ast.newName(new String[] { "java", "util", "Set" }));
cu.imports().add(id);
TypeDeclaration td = ast.newTypeDeclaration();
td.setName(ast.newSimpleName("Foo"));
TypeParameter tp = ast.newTypeParameter();
tp.setName(ast.newSimpleName("X"));
td.typeParameters().add(tp);
cu.types().add(td);
MethodDeclaration md = ast.newMethodDeclaration();
td.bodyDeclarations().add(md);
Block block = ast.newBlock();
md.setBody(block);
MethodInvocation mi = ast.newMethodInvocation();
mi.setName(ast.newSimpleName("x"));
ExpressionStatement e = ast.newExpressionStatement(mi);
block.statements().add(e);
System.out.println(cu);
I can get this output:
package foo;
import java.util.Set;
class Foo<X> {
void MISSING(){
x();
}
}
You can use Roaster (https://github.com/forge/roaster) to do code generation.
Here is an example:
JavaClassSource source = Roaster.create(JavaClassSource.class);
source.setName("MyClass").setPublic();
source.addMethod().setName("testMethod").setPrivate().setBody("return null;")
.setReturnType(String.class).addAnnotation(MyAnnotation.class);
System.out.println(source);
will display the following output:
public class MyClass {
private String testMethod() {
return null;
}
}
Another alternative is Eclipse JDT's AST which is good if you need to rewrite arbitrary Java source code rather than just generate source code.
(and I believe it can be used independently from eclipse).
The Eclipse JET project can be used to do source generation. I don't think it's API is exactly like the one you described, but every time I've heard of a project doing Java source generation they've used JET or a homegrown tool.
Don't know of a library, but a generic template engine might be all you need. There are a bunch of them, I personally have had good experience with FreeMarker
I built something that looks very much like your theoretical DSL, called "sourcegen", but technically instead of a util project for an ORM I wrote. The DSL looks like:
#Test
public void testTwoMethods() {
GClass gc = new GClass("foo.bar.Foo");
GMethod hello = gc.getMethod("hello");
hello.arguments("String foo");
hello.setBody("return 'Hi' + foo;");
GMethod goodbye = gc.getMethod("goodbye");
goodbye.arguments("String foo");
goodbye.setBody("return 'Bye' + foo;");
Assert.assertEquals(
Join.lines(new Object[] {
"package foo.bar;",
"",
"public class Foo {",
"",
" public void hello(String foo) {",
" return \"Hi\" + foo;",
" }",
"",
" public void goodbye(String foo) {",
" return \"Bye\" + foo;",
" }",
"",
"}",
"" }),
gc.toCode());
}
https://github.com/stephenh/joist/blob/master/util/src/test/java/joist/sourcegen/GClassTest.java
It also does some neat things like "Auto-organize imports" any FQCNs in parameters/return types, auto-pruning any old files that were not touched in this codegen run, correctly indenting inner classes, etc.
The idea is that generated code should be pretty to look at it, with no warnings (unused imports, etc.), just like the rest of your code. So much generated code is ugly to read...it's horrible.
Anyway, there is not a lot of docs, but I think the API is pretty simple/intuitive. The Maven repo is here if anyone is interested.
If you REALLY need the source, I don't know of anything that generates source. You can however use ASM or CGLIB to directly create the .class files.
You might be able to generate source from these, but I've only used them to generate bytecode.
I was doing it myself for a mock generator tool. It's a very simple task, even if you need to follow Sun formatting guidelines. I bet you'd finish the code that does it faster then you found something that fits your goal on the Internet.
You've basically outlined the API yourself. Just fill it with the actual code now!
There is also StringTemplate. It is by the author of ANTLR and is quite powerful.
There is new project write-it-once. Template based code generator. You write custom template using Groovy, and generate file depending on java reflections. It's the simplest way to generate any file. You can make getters/settest/toString by generating AspectJ files, SQL based on JPA annotations, inserts / updates based on enums and so on.
Template example:
package ${cls.package.name};
public class ${cls.shortName}Builder {
public static ${cls.name}Builder builder() {
return new ${cls.name}Builder();
}
<% for(field in cls.fields) {%>
private ${field.type.name} ${field.name};
<% } %>
<% for(field in cls.fields) {%>
public ${cls.name}Builder ${field.name}(${field.type.name} ${field.name}) {
this.${field.name} = ${field.name};
return this;
}
<% } %>
public ${cls.name} build() {
final ${cls.name} data = new ${cls.name}();
<% for(field in cls.fields) {%>
data.${field.setter.name}(this.${field.name});
<% } %>
return data;
}
}
It really depends on what you are trying to do. Code generation is a topic within itself. Without a specific use-case, I suggest looking at velocity code generation/template library. Also, if you are doing the code generation offline, I would suggest using something like ArgoUML to go from UML diagram/Object model to Java code.
Exemple :
1/
private JFieldVar generatedField;
2/
String className = "class name";
/* package name */
JPackage jp = jCodeModel._package("package name ");
/* class name */
JDefinedClass jclass = jp._class(className);
/* add comment */
JDocComment jDocComment = jclass.javadoc();
jDocComment.add("By AUTOMAT D.I.T tools : " + new Date() +" => " + className);
// génération des getter & setter & attribues
// create attribue
this.generatedField = jclass.field(JMod.PRIVATE, Integer.class)
, "attribue name ");
// getter
JMethod getter = jclass.method(JMod.PUBLIC, Integer.class)
, "attribue name ");
getter.body()._return(this.generatedField);
// setter
JMethod setter = jclass.method(JMod.PUBLIC, Integer.class)
,"attribue name ");
// create setter paramétre
JVar setParam = setter.param(getTypeDetailsForCodeModel(Integer.class,"param name");
// affectation ( this.param = setParam )
setter.body().assign(JExpr._this().ref(this.generatedField), setParam);
jCodeModel.build(new File("path c://javaSrc//"));
Here is a JSON-to-POJO project that looks interesting:
http://www.jsonschema2pojo.org/