Skip to content

Commit 1d9fa20

Browse files
author
jbachorik
committed
service injection for fields; fixes in the injection logic
1 parent 4e285a8 commit 1d9fa20

19 files changed

Lines changed: 1216 additions & 403 deletions

make/build.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
<property name="maven-staging-repository-id" value="sonatype-nexus-staging" />
77
<property name="maven-staging-repository-url" value="https://oss.sonatype.org/service/local/staging/deploy/maven2" />
88

9-
<property name="agent.excludes" value="**/dtrace/* **/btrace/*.class **/asm/signature/** **/asm/tree/** **/asm/util/** **/asm/xml/** **/aggregation/* **/annotations/* **/compiler/* **/client/* **/comm/* **/api/**/* **/spi/**/* **/instr/** **/META-INF/*"/>
10-
<property name="boot.excludes" value="**/dtrace/* **/agent/* **/compiler/* **/client/* **/resources/* **/runtime/* **/util/**/* **/asm/** **/api/**/* **/spi/**/*"/>
9+
<property name="agent.excludes" value="**/dtrace/* **/btrace/*.class **/asm/signature/** **/asm/tree/** **/asm/util/** **/asm/xml/** **/aggregation/* **/annotations/* **/compiler/* **/client/* **/comm/* com/sun/btrace/api/**/* com/sun/btrace/spi/**/* **/instr/** **/META-INF/*"/>
10+
<property name="boot.excludes" value="**/dtrace/* **/agent/* **/compiler/* **/client/* **/resources/* **/runtime/* **/util/**/* **/asm/** com/sun/btrace/api/**/* com/sun/btrace/spi/**/*"/>
1111
<property name="client.excludes" value="**/runtime/* **/agent/* **/util/TimeStamp* **/util/MethodId **/util/SamplingSupport **/util/templates/**/* **/instr/** **/META-INF/*"/>
1212

1313
<target name="prepare" depends="load.properties">

src/share/classes/com/sun/btrace/annotations/Injected.java

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,23 @@
3030
import java.lang.annotation.Target;
3131

3232
/**
33-
*
33+
* Annotates a field as an injected service.
3434
* @author Jaroslav Bachorik
3535
*/
36-
@Target({ElementType.FIELD, ElementType.LOCAL_VARIABLE})
36+
@Target(ElementType.FIELD)
3737
@Retention(RetentionPolicy.CLASS)
3838
public @interface Injected {
39-
39+
/**
40+
* The injected service type
41+
* @return
42+
*/
43+
ServiceType value() default ServiceType.SIMPLE;
44+
/**
45+
* The factory method to be used.
46+
* <p>
47+
* It must be a static method declared by the service class
48+
* and returning the service class instance
49+
* @return The name of the static method to be used as the factory method or an empty string
50+
*/
51+
String factoryMethod() default "";
4052
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
24+
*/
25+
package com.sun.btrace.annotations;
26+
27+
import com.sun.btrace.BTraceRuntime;
28+
29+
/**
30+
* Service type enumeration
31+
* @author Jaroslav Bachorik
32+
*/
33+
public enum ServiceType {
34+
/**
35+
* A simple service; possibly a globally shared singleton
36+
*/
37+
SIMPLE,
38+
/**
39+
* A runtime-aware service; requires an instance per {@linkplain BTraceRuntime}
40+
*/
41+
RUNTIME
42+
}

src/share/classes/com/sun/btrace/compiler/Postprocessor.java

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
/*
2-
* Copyright 2008-2010 Sun Microsystems, Inc. All Rights Reserved.
2+
* Copyright (c) 2010, 2014, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
66
* under the terms of the GNU General Public License version 2 only, as
7-
* published by the Free Software Foundation. Sun designates this
7+
* published by the Free Software Foundation. Oracle designates this
88
* particular file as subject to the "Classpath" exception as provided
9-
* by Sun in the LICENSE file that accompanied this code.
9+
* by Oracle in the LICENSE file that accompanied this code.
1010
*
1111
* This code is distributed in the hope that it will be useful, but WITHOUT
1212
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@@ -18,9 +18,9 @@
1818
* 2 along with this work; if not, write to the Free Software Foundation,
1919
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2020
*
21-
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22-
* CA 95054 USA or visit www.sun.com if you need additional information or
23-
* have any questions.
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
2424
*/
2525

2626
package com.sun.btrace.compiler;
@@ -45,7 +45,7 @@
4545
* @author Jaroslav Bachorik
4646
*/
4747
public class Postprocessor extends ClassVisitor {
48-
private List<FieldDescriptor> fields = new ArrayList<FieldDescriptor>();
48+
private final List<FieldDescriptor> fields = new ArrayList<FieldDescriptor>();
4949
private boolean shortSyntax = false;
5050
private String className = "";
5151

@@ -90,24 +90,20 @@ public MethodVisitor visitMethod(int access, String name, String desc, String si
9090
@Override
9191
public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, final Object value) {
9292
if (!shortSyntax) return super.visitField(access, name, desc, signature, value);
93-
93+
9494
final List<Attribute> attrs = new ArrayList<Attribute>();
9595
return new FieldVisitor(Opcodes.ASM4) {
9696

97-
public AnnotationVisitor visitAnnotation(String string, boolean bln) {
98-
return new AnnotationVisitor(Opcodes.ASM4){
99-
};
100-
}
101-
10297
public void visitAttribute(Attribute atrbt) {
98+
super.visitAttribute(atrbt);
10399
attrs.add(atrbt);
104-
105100
}
106101

107102
public void visitEnd() {
108103
FieldDescriptor fd = new FieldDescriptor(access, name, desc,
109104
signature, value, attrs);
110105
fields.add(fd);
106+
super.visitEnd();
111107
}
112108
};
113109
}
@@ -350,7 +346,7 @@ public void visitInsn(int opcode) {
350346
simulatedStack.push(Boolean.FALSE);
351347
break;
352348
}
353-
349+
354350
// one operand instructions
355351
case Opcodes.INEG:
356352
case Opcodes.FNEG:
@@ -373,7 +369,7 @@ public void visitInsn(int opcode) {
373369
simulatedStack.push(Boolean.FALSE); // extending the original value by one slot
374370
break;
375371
}
376-
372+
377373
// two operand instructions
378374
case Opcodes.LADD:
379375
case Opcodes.DADD:
@@ -390,7 +386,7 @@ public void visitInsn(int opcode) {
390386
case Opcodes.LUSHR:
391387
case Opcodes.LAND:
392388
case Opcodes.LOR:
393-
case Opcodes.LXOR:
389+
case Opcodes.LXOR:
394390
case Opcodes.LALOAD:
395391
case Opcodes.DALOAD: {
396392
simulatedStack.pop();

src/share/classes/com/sun/btrace/compiler/VerifierVisitor.java

Lines changed: 67 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
/*
2-
* Copyright 2008-2010 Sun Microsystems, Inc. All Rights Reserved.
2+
* Copyright (c) 2008, 2014, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
66
* under the terms of the GNU General Public License version 2 only, as
7-
* published by the Free Software Foundation. Sun designates this
7+
* published by the Free Software Foundation. Oracle designates this
88
* particular file as subject to the "Classpath" exception as provided
9-
* by Sun in the LICENSE file that accompanied this code.
9+
* by Oracle in the LICENSE file that accompanied this code.
1010
*
1111
* This code is distributed in the hope that it will be useful, but WITHOUT
1212
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@@ -18,9 +18,9 @@
1818
* 2 along with this work; if not, write to the Free Software Foundation,
1919
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
2020
*
21-
* Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22-
* CA 95054 USA or visit www.sun.com if you need additional information or
23-
* have any questions.
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
2424
*/
2525

2626
package com.sun.btrace.compiler;
@@ -69,6 +69,8 @@ public class VerifierVisitor extends TreeScanner<Boolean, Void> {
6969

7070
private boolean shortSyntax = false;
7171
private TypeMirror btraceServiceTm = null;
72+
private TypeMirror runtimeServiceTm = null;
73+
private TypeMirror simpleServiceTm = null;
7274
private TypeMirror serviceInjectorTm = null;
7375

7476
public VerifierVisitor(Verifier verifier, Element clzElement) {
@@ -81,6 +83,8 @@ public VerifierVisitor(Verifier verifier, Element clzElement) {
8183
}
8284
sharedMethods = shared.toArray(new ExecutableElement[shared.size()]);
8385
btraceServiceTm = verifier.getElementUtils().getTypeElement("com.sun.btrace.services.spi.BTraceService").asType();
86+
runtimeServiceTm = verifier.getElementUtils().getTypeElement("com.sun.btrace.services.spi.RuntimeService").asType();
87+
simpleServiceTm = verifier.getElementUtils().getTypeElement("com.sun.btrace.services.spi.SimpleService").asType();
8488
serviceInjectorTm = verifier.getElementUtils().getTypeElement("com.sun.btrace.services.api.Service").asType();
8589
}
8690

@@ -90,8 +94,13 @@ public Boolean visitMethodInvocation(MethodInvocationTree node, Void v) {
9094
if (e.getKind() == ElementKind.METHOD) {
9195
ExecutableElement ee = (ExecutableElement)e;
9296
TypeMirror owner = ee.getEnclosingElement().asType();
93-
if (verifier.getTypeUtils().isSubtype(owner, btraceServiceTm) ||
94-
verifier.getTypeUtils().isSubtype(owner, serviceInjectorTm)) {
97+
if (verifier.getTypeUtils().isSubtype(owner, serviceInjectorTm)) {
98+
if (validateInjectionParams(node)) {
99+
return super.visitMethodInvocation(node, v);
100+
} else {
101+
return reportError("service.injector.literals", node);
102+
}
103+
} else if (verifier.getTypeUtils().isSubtype(owner, btraceServiceTm)) {
95104
return super.visitMethodInvocation(node, v);
96105
}
97106
}
@@ -267,9 +276,7 @@ public Boolean visitMethod(MethodTree node, Void v) {
267276
if (name.contentEquals("<init>")) {
268277
return super.visitMethod(node, v);
269278
} else {
270-
verifier.getMessager().printMessage(Diagnostic.Kind.NOTE, "Going to check for sampler");
271279
if (!checkSampling(node)) {
272-
verifier.getMessager().printMessage(Diagnostic.Kind.NOTE, "Verifier should fail");
273280
return false;
274281
}
275282
if (isExitHandler(node)) {
@@ -384,9 +391,31 @@ public Boolean visitTry(TryTree node, Void v) {
384391
public Boolean visitVariable(VariableTree vt, Void p) {
385392
VariableElement ve = (VariableElement)getElement(vt);
386393

387-
if (verifier.getTypeUtils().isSubtype(ve.asType(), btraceServiceTm)) {
388-
if (ve.getAnnotation(Injected.class) == null) {
389-
return reportError("missing.injected", vt);
394+
if (ve.getEnclosingElement().getKind() == ElementKind.CLASS) {
395+
// only applying to fields
396+
if (verifier.getTypeUtils().isSubtype(ve.asType(), btraceServiceTm)) {
397+
Injected i = ve.getAnnotation(Injected.class);
398+
if (i == null) {
399+
return reportError("missing.injected", vt);
400+
} else {
401+
switch (i.value()) {
402+
case RUNTIME: {
403+
if (!verifier.getTypeUtils().isSubtype(ve.asType(), runtimeServiceTm)) {
404+
return reportError("injected.no.runtime", vt);
405+
}
406+
break;
407+
}
408+
case SIMPLE: {
409+
if (!verifier.getTypeUtils().isSubtype(ve.asType(), simpleServiceTm)) {
410+
return reportError("injected.no.simple", vt);
411+
}
412+
break;
413+
}
414+
}
415+
}
416+
if (vt.getInitializer() != null) {
417+
return reportError("injected.no.initializer", vt.getInitializer());
418+
}
390419
}
391420
}
392421

@@ -586,4 +615,29 @@ private Element getElement(Tree t) {
586615
TreePath tp = verifier.getTreeUtils().getPath(verifier.getCompilationUnit(), t);
587616
return verifier.getTreeUtils().getElement(tp);
588617
}
618+
619+
private boolean validateInjectionParams(MethodInvocationTree node) {
620+
boolean allLiterals = true;
621+
outer:
622+
for(ExpressionTree arg : node.getArguments()) {
623+
switch (arg.getKind()) {
624+
case MEMBER_SELECT: {
625+
if (!arg.toString().endsWith(".class")) {
626+
allLiterals = false;
627+
break outer;
628+
}
629+
}
630+
case STRING_LITERAL: {
631+
// allowed parameters
632+
break;
633+
}
634+
default: {
635+
allLiterals = false;
636+
break outer;
637+
}
638+
}
639+
}
640+
return allLiterals;
641+
}
642+
589643
}

src/share/classes/com/sun/btrace/resources/messages.properties

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ called-instance.desc.invalid = @CalledInstance annotation applicable only for Ki
4343
onexit.invalid = @OnExit annotation applicable only to methods with signature (int)void
4444
onerror.invalid = @OnError annotation applicable only to methods with signature (java.lang.Throwable)void
4545
sampler.invalid.location = @Sampled annotation supported only for @OnMethod annotated classes with Kind of [ENTRY, RETURN, ERROR, CALL]
46-
missing.injected = Service variables must be annotated by @Injected
46+
missing.injected = Service fields must be annotated by @Injected
47+
injected.no.initializer = Injected fields must not use initializer
48+
injected.no.runtime = Injection kind is RUNTIME but the service is not a subclass of com.sun.btrace.services.spi.RuntimeService
49+
injected.no.initializer = Injection kind is SIMPLE but the service is not a subclass of com.sun.btrace.services.spi.SimpleService
50+
service.injector.literals = May only use literals as Service.* methods parameters
4751
agent.no.instance.variables=instance variables are not allowed
4852
agent.unsafe.not.allowed=Unsafe mode, requested by the script, not allowed
4953

src/share/classes/com/sun/btrace/runtime/Assembler.java

Lines changed: 46 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,40 @@
11
/*
2-
* To change this license header, choose License Headers in Project Properties.
3-
* To change this template file, choose Tools | Templates
4-
* and open the template in the editor.
2+
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation. Oracle designates this
8+
* particular file as subject to the "Classpath" exception as provided
9+
* by Oracle in the LICENSE file that accompanied this code.
10+
*
11+
* This code is distributed in the hope that it will be useful, but WITHOUT
12+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14+
* version 2 for more details (a copy is included in the LICENSE file that
15+
* accompanied this code).
16+
*
17+
* You should have received a copy of the GNU General Public License version
18+
* 2 along with this work; if not, write to the Free Software Foundation,
19+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20+
*
21+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22+
* or visit www.oracle.com if you need additional information or have any
23+
* questions.
524
*/
625
package com.sun.btrace.runtime;
726

827
import com.sun.btrace.org.objectweb.asm.MethodVisitor;
28+
import com.sun.btrace.org.objectweb.asm.Opcodes;
929
import static com.sun.btrace.org.objectweb.asm.Opcodes.*;
1030
import static com.sun.btrace.runtime.Constants.*;
1131

1232
import com.sun.btrace.org.objectweb.asm.Type;
1333

1434
/**
15-
*
16-
* @author jbachorik
35+
* Convenient fluent wrapper over the ASM method visitor
36+
*
37+
* @author Jaroslav Bachorik
1738
*/
1839
final public class Assembler {
1940
private final MethodVisitor mv;
@@ -92,6 +113,26 @@ public Assembler storeLocal(Type type, int index) {
92113
return this;
93114
}
94115

116+
public Assembler storeField(Type owner, String name, Type t) {
117+
mv.visitFieldInsn(Opcodes.PUTFIELD, owner.getInternalName(), name, t.getDescriptor());
118+
return this;
119+
}
120+
121+
public Assembler storeStaticField(Type owner, String name, Type t) {
122+
mv.visitFieldInsn(Opcodes.PUTSTATIC, owner.getInternalName(), name, t.getDescriptor());
123+
return this;
124+
}
125+
126+
public Assembler loadField(Type owner, String name, Type t) {
127+
mv.visitFieldInsn(Opcodes.GETFIELD, owner.getInternalName(), name, t.getDescriptor());
128+
return this;
129+
}
130+
131+
public Assembler loadStaticField(Type owner, String name, Type t) {
132+
mv.visitFieldInsn(Opcodes.GETSTATIC, owner.getInternalName(), name, t.getDescriptor());
133+
return this;
134+
}
135+
95136
public Assembler pop() {
96137
mv.visitInsn(POP);
97138
return this;

0 commit comments

Comments
 (0)